Redis概述

Redis是一种基于键值对的NoSQL数据库,它提供了对多种数据类型(字符串、哈希、列表、集合、有序集合、位图等)的支持,能够满足很多应用场景的需求。Redis将数据放在内存中,因此读写性能是非常惊人的。与此同时,Redis也提供了持久化机制,能够将内存中的数据保存到硬盘上,在发生意外状况时数据也不会丢掉。此外,Redis还支持键过期、地理信息运算、发布订阅、事务、管道、Lua脚本扩展等功能,总而言之,Redis的功能和性能都非常强大,如果项目中要实现高速缓存和消息队列这样的服务,直接交给Redis就可以了。目前,国内外很多著名的企业和商业项目都使用了Redis,包括:Twitter、Github、StackOverflow、新浪微博、百度、优酷土豆、美团、小米、唯品会等。

Redis简介

2008年,一个名为Salvatore Sanfilippo的程序员为他开发的LLOOGG项目定制了专属的数据库(因为之前他无论怎样优化MySQL,系统性能已经无法再提升了),这项工作的成果就是Redis的初始版本。后来他将Redis的代码放到了全球最大的代码托管平台Github,从那以后,Redis引发了大量开发者的好评和关注,继而有数百人参与了Redis的开发和维护,这使得Redis的功能越来越强大和性能越来越好。

Redis是REmote DIctionary Server的缩写,它是一个用ANSI C编写的高性能的key-value存储系统,与其他的key-value存储系统相比,Redis有以下一些特点(也是优点):

  • Redis的读写性能极高,并且有丰富的特性(发布/订阅、事务、通知等)。
  • Redis支持数据的持久化(RDB和AOF两种方式),可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis支持多种数据类型,包括:string、hash、list、set,zset、bitmap、hyperloglog等。
  • Redis支持主从复制(实现读写分析)以及哨兵模式(监控master是否宕机并自动调整配置)。
  • Redis支持分布式集群,可以很容易的通过水平扩展来提升系统的整体性能。
  • Redis基于TCP提供的可靠传输服务进行通信,很多编程语言都提供了Redis客户端支持。

Redis的应用场景

  1. 高速缓存 - 将不常变化但又经常被访问的热点数据放到Redis数据库中,可以大大降低关系型数据库的压力,从而提升系统的响应性能。
  2. 排行榜 - 很多网站都有排行榜功能,利用Redis中的列表和有序集合可以非常方便的构造各种排行榜系统。
  3. 商品秒杀/投票点赞 - Redis提供了对计数操作的支持,网站上常见的秒杀、点赞等功能都可以利用Redis的计数器通过+1或-1的操作来实现,从而避免了使用关系型数据的update操作。
  4. 分布式锁 - 利用Redis可以跨多台服务器实现分布式锁(类似于线程锁,但是能够被多台机器上的多个线程或进程共享)的功能,用于实现一个阻塞式操作。
  5. 消息队列 - 消息队列和高速缓存一样,是一个大型网站不可缺少的基础服务,可以实现业务解耦和非实时业务削峰等特性,这些我们都会在后面的项目中为大家展示。

Redis的安装和配置

可以使用Linux系统的包管理工具(如yum)来安装Redis,也可以通过在Redis的官方网站下载Redis的源代码,解压缩解归档之后通过make工具对源代码进行构建并安装,在更新这篇文档时,Redis官方提供的最新稳定版本是Redis 5.0.10

下载:

  1. wget https://download.redis.io/releases/redis-5.0.10.tar.gz

解压缩和解归档:

  1. tar -zxf redis-5.0.10.tar.gz

进入Redis源代码目录:

  1. cd redis-5.0.10

构建和安装:

  1. make && make install

在redis源代码目录下有一个名为redis.conf的配置文件,我们可以先查看一下该文件。

  1. vim redis.conf

下面我们对Redis的配置文件进行一个扼要的介绍。

配置Redis服务的IP地址和端口:

Redis概述 - 图1

配置底层有多少个数据库:

Redis概述 - 图2

配置Redis的持久化机制 - RDB。

Redis概述 - 图3

Redis概述 - 图4

配置Redis的持久化机制 - AOF:

Redis概述 - 图5

配置访问Redis服务器的口令:

Redis概述 - 图6

配置Redis的主从复制(通过主从复制可以实现读写分离):

Redis概述 - 图7

配置慢查询:

Redis概述 - 图8

上面这些内容就是Redis的基本配置,如果你对上面的内容感到困惑也没有关系,先把Redis用起来再回头去推敲这些内容就行了。如果想找一些参考书,《Redis开发与运维》是一本不错的入门读物,而《Redis实战》是不错的进阶读物。

Redis的服务器和客户端

接下来启动Redis服务器,下面的方式将以默认的配置启动Redis服务。

  1. redis-server

如果希望修改Redis的配置(如端口、认证口令、持久化方式等),可以通过下面两种方式。

方式一:通过参数指定认证口令和AOF持久化方式。

  1. redis-server --requirepass yourpass --appendonly yes

方式二:通过指定的配置文件来修改Redis的配置。

  1. redis-server /root/redis-5.0.10/redis.conf

下面我们使用第一种方式来启动Redis并将其置于后台运行,将Redis产生的输出重定向到名为redis.log的文件中。

  1. redis-server --requirepass yourpass > redis.log &

可以通过ps或者netstat来检查Redis服务器是否启动成功。

  1. ps -ef | grep redis-server
  2. netstat -nap | grep redis-server

接下来,我们尝试用Redis命令行工具redis-cli去连接服务器,该工具默认连接本机的6379端口,如果需要指定Redis服务器和端口,可以使用-h-p参数分别进行指定。

  1. redis-cli

进入命令行工具后,就可以通过Redis的命令来操作Redis服务器,如下所示。

  1. 127.0.0.1:6379> auth yourpass
  2. OK
  3. 127.0.0.1:6379> ping
  4. PONG
  5. 127.0.0.1:6379>

Redis有着非常丰富的数据类型,也有很多的命令来操作这些数据,具体的内容可以查看Redis命令参考,在这个网站上,除了Redis的命令参考,还有Redis的详细文档,其中包括了通知、事务、主从复制、持久化、哨兵、集群等内容。

Redis概述 - 图9

说明:上面的插图来自付磊和张益军编著的《Redis开发与运维》一书。

  1. 127.0.0.1:6379> set username admin
  2. OK
  3. 127.0.0.1:6379> get username
  4. "admin"
  5. 127.0.0.1:6379> set password "123456" ex 300
  6. OK
  7. 127.0.0.1:6379> get password
  8. "123456"
  9. 127.0.0.1:6379> ttl username
  10. (integer) -1
  11. 127.0.0.1:6379> ttl password
  12. (integer) 286
  13. 127.0.0.1:6379> hset stu1 name hao
  14. (integer) 0
  15. 127.0.0.1:6379> hset stu1 age 38
  16. (integer) 1
  17. 127.0.0.1:6379> hset stu1 gender male
  18. (integer) 1
  19. 127.0.0.1:6379> hgetall stu1
  20. 1) "name"
  21. 2) "hao"
  22. 3) "age"
  23. 4) "38"
  24. 5) "gender"
  25. 6) "male"
  26. 127.0.0.1:6379> hvals stu1
  27. 1) "hao"
  28. 2) "38"
  29. 3) "male"
  30. 127.0.0.1:6379> hmset stu2 name wang age 18 gender female tel 13566778899
  31. OK
  32. 127.0.0.1:6379> hgetall stu2
  33. 1) "name"
  34. 2) "wang"
  35. 3) "age"
  36. 4) "18"
  37. 5) "gender"
  38. 6) "female"
  39. 7) "tel"
  40. 8) "13566778899"
  41. 127.0.0.1:6379> lpush nums 1 2 3 4 5
  42. (integer) 5
  43. 127.0.0.1:6379> lrange nums 0 -1
  44. 1) "5"
  45. 2) "4"
  46. 3) "3"
  47. 4) "2"
  48. 5) "1"
  49. 127.0.0.1:6379> lpop nums
  50. "5"
  51. 127.0.0.1:6379> lpop nums
  52. "4"
  53. 127.0.0.1:6379> rpop nums
  54. "1"
  55. 127.0.0.1:6379> rpop nums
  56. "2"
  57. 127.0.0.1:6379> sadd fruits apple banana orange apple grape grape
  58. (integer) 4
  59. 127.0.0.1:6379> scard fruits
  60. (integer) 4
  61. 127.0.0.1:6379> smembers fruits
  62. 1) "grape"
  63. 2) "orange"
  64. 3) "banana"
  65. 4) "apple"
  66. 127.0.0.1:6379> sismember fruits apple
  67. (integer) 1
  68. 127.0.0.1:6379> sismember fruits durian
  69. (integer) 0
  70. 127.0.0.1:6379> sadd nums1 1 2 3 4 5
  71. (integer) 5
  72. 127.0.0.1:6379> sadd nums2 2 4 6 8
  73. (integer) 4
  74. 127.0.0.1:6379> sinter nums1 nums2
  75. 1) "2"
  76. 2) "4"
  77. 127.0.0.1:6379> sunion nums1 nums2
  78. 1) "1"
  79. 2) "2"
  80. 3) "3"
  81. 4) "4"
  82. 5) "5"
  83. 6) "6"
  84. 7) "8"
  85. 127.0.0.1:6379> sdiff nums1 nums2
  86. 1) "1"
  87. 2) "3"
  88. 3) "5"
  89. 127.0.0.1:6379> zadd topsinger 5234 zhangxy 1978 chenyx 2235 zhoujl 3520 xuezq
  90. (integer) 4
  91. 127.0.0.1:6379> zrange topsinger 0 -1 withscores
  92. 1) "chenyx"
  93. 2) "1978"
  94. 3) "zhoujl"
  95. 4) "2235"
  96. 5) "xuezq"
  97. 6) "3520"
  98. 7) "zhangxy"
  99. 8) "5234"
  100. 127.0.0.1:6379> zrevrange topsinger 0 -1
  101. 1) "zhangxy"
  102. 2) "xuezq"
  103. 3) "zhoujl"
  104. 4) "chenyx"
  105. 127.0.0.1:6379> zrevrank topsinger zhoujl
  106. (integer) 2
  107. 127.0.0.1:6379> geoadd pois 116.39738549206541 39.90862689286386 tiananmen
  108. (integer) 1
  109. 127.0.0.1:6379> geoadd pois 116.27172936413572 39.99135172904494 yiheyuan
  110. (integer) 1
  111. 127.0.0.1:6379> geoadd pois 117.27766503308104 40.65332064313784 gubeishuizhen
  112. (integer) 1
  113. 127.0.0.1:6379> geodist pois tiananmen gubeishuizhen km
  114. "111.5333"
  115. 127.0.0.1:6379> geodist pois tiananmen yiheyuan km
  116. "14.1230"
  117. 127.0.0.1:6379> georadius pois 116.86499108288572 40.40149669363615 50 km withdist
  118. 1) 1) "gubeishuizhen"
  119. 2) "44.7408"

在Python程序中使用Redis

可以使用pip安装名为redis的三方库,该三方库的核心是一个名为Redis的类,Redis对象代表一个Redis客户端,通过该客户端可以向Redis服务器发送命令并获取执行的结果。上面我们在Redis客户端中使用的命令基本上就是Redis对象可以接收的消息,所以如果了解了Redis的命令就可以在Python中玩转Redis。

  1. pip3 install redis

进入Python交互式环境,使用redis三方库来操作Redis。

  1. >>> import redis
  2. >>>
  3. >>> client = redis.Redis(host='127.0.0.1', port=6379, password='yourpass')
  4. >>>
  5. >>> client.set('username', 'admin')
  6. True
  7. >>> client.hset('student', 'name', 'luohao')
  8. 1
  9. >>> client.hset('student', 'age', 40)
  10. 1
  11. >>> client.keys('*')
  12. [b'username', b'student']
  13. >>> client.get('username')
  14. b'admin'
  15. >>> client.hgetall('student')
  16. {b'name': b'luohao', b'age': b'40'}