Redis介绍及安装配置
一、Redis介绍
Redis是一个开源(BSD许可)的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。由于Redis采用运行在内存中的数据集工作方式,其性能卓越,能支持超过100K+每秒的读写频率。它支持多种类型的数据结构,如字符串(strings), 散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)与范围查询和地理空间(geospatial)索引半径查询。Redis内置了复制(replication), LUA脚本(Lua scripting),LRU淘汰机制,事务实现(transactions),发布订阅(publish/subscribe)和不同级别的磁盘持久化(persistence)等能力, 并通过Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(high availability)。
Redis的主要功能都是基于单线程网络模型实现,也就是说Redis使用一个线程来服务所有的客户端请求,同时Redis采用了非阻塞式IO,并精细地优化各种命令的算法和时间复杂度,大部分命令的算法都是O(1)的,具体可以看Redis命令参考。
另外Redis的大部分操作都是原子性的(简单的单线程模型),同时Redis还支持对几个操作全并后的原子性执行。列如:字符串(strings)的append命令;散列(hashes)的hincrby命令;列表(lists)的lpush命令;集合(sets)计算交集sinter命令,计算并集union命令和计算差集sdiff命令;或者在有序集合(sorted sets)里面获取成员的最高排名zrangebyscore命令等。
二、Redis应用
2.1 缓存
作为key-value形态的内存数据库,Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数据非常简单,只需要通过string
类型将序列化后的对象存起来即可。
2.2 消息队列
Redis 中list
的数据结构实现是双向链表,所以可以非常便捷的应用于消息队列(生产者 / 消费者模型)。消息的生产者只需要通过lpush
将消息放入 list,消费者便可以通过rpop
取出该消息,并且可以保证消息的有序性。如果需要实现带有优先级的消息队列也可以选择sorted set
。而pub/sub
功能也可以用作发布者 / 订阅者模型的消息。无论使用何种方式,由于 Redis 拥有持久化功能,也不需要担心由于服务器故障导致消息丢失的情况。
2.3 关注列表
list
列表除了做队列,还应用于各大社交软件的用户关注列表中,比如说在直播中,主播的粉丝数。更复杂一点的就是像微博这种,每一个用户都会有一个关注列表,一个粉丝列表。用户可以查看自己的关注,粉丝列表,也可以查看别人的关注,粉丝列表。并且,要展示列表里每个人与当前查看者的关注状态。状态的可能性就是上面讲到得四种关系状态。
2.4 排行榜
使用sorted set
和一个计算热度的算法便可以轻松打造一个热度排行榜,zrevrangebyscore
可以得到以分数倒序排列的序列,zrank
可以得到一个成员在该排行榜的位置(是分数正序排列时的位置,如果要获取倒序排列时的位置需要用zcard
-zrank
)。
2.5 计数器
计数功能应该是最适合 Redis 的使用场景之一了,因为它高频率读写的特征可以完全发挥 Redis 作为内存数据库的高效。在 Redis 的数据结构中,string
、hash
和sorted set
都提供了incr
方法用于原子性的自增操作。下面举例说明一下它们各自的使用场景:
- 如果应用需要显示每天的注册用户数,便可以使用
string
作为计数器,设定一个名为REGISTERED_COUNT_TODAY
的 key,并在初始化时给它设置一个到凌晨 0 点的过期时间,每当用户注册成功后便使用incr
命令使该 key 增长 1,同时当每天凌晨 0 点后,这个计数器都会因为 key 过期使值清零。 - 每条微博都有点赞数、评论数、转发数和浏览数四条属性,这时用
hash
进行计数会更好,将该计数器的 key 设为weibo:weibo_id
,hash
的 field 为like_number
、comment_number
、forward_number
和view_number
,在对应操作后通过hincrby
使hash 中
的 field 自增。 - 如果应用有一个发帖排行榜的功能,便选择
sorted set
吧,将集合的 key 设为POST_RANK
。当用户发帖后,使用zincrby
将该用户 id 的 score 增长 1。sorted set
会重新进行排序,用户所在排行榜的位置也就会得到实时的更新。
2.6 分布式锁
在Redis 2.6.12版本开始,string
的set
命令增加了三个参数:
EX
:设置键的过期时间(单位为秒)PX
:设置键的过期时间(单位为毫秒)NX
|XX
:当设置为NX
时,仅当 key 存在时才进行操作,设置为XX
时,仅当 key 不存在才会进行操作由于这个操作是原子性的,可以简单地以此实现一个分布式的锁,例如:
set key "lock" EX 1 XX
如果这个操作返回false
,说明key的添加不成功,也就是当前有人在占用这把锁。而如果返回true
,则说明得了锁,便可以继续进行操作,并且在操作后通过del
命令释放掉锁。并且即使程序因为某些原因并没有释放锁,由于设置了过期时间,该锁也会在1秒后自动释放,不会影响到其他程序的运行。
三、Redis安装
由于REDIS使用单线程处理请求,CPU的快慢最对REDIS的性能有较大影响,官方建议INTEL的CPU,其效率能比AMD高一倍左右。
下载Redis:wget http://download.redis.io/releases/redis-3.2.6.tar.gz
在安装Redis之前,需要安装Redis的依赖程序tcl,如果不安装tcl在Redis执行make test的时候就会报错的哦。
$ yum install -y tcl tel-devel
$ tar xvf 3.2.6.tar.gz -C /usr/local $ cd /usr/local/ $ mv redis-3.2.6 redis $ cd redis $ make $ make test $ make install $ mkdir /etc/redis $ cp redis/redis.conf /etc/
标准配置
$ mkdir /data/redis/member-6379 -p $ mkdir /data/redis/member-6379/{log,conf,pid,data} $ cp /usr/local/redis/redis.conf /data/redis/member-6379/conf/
以redis用户启动redis(配置文件信息请看:Redis配置文件详解(生产可用))
$ useradd -s /bin/false -M redis $ sudo -u redis `which redis-server` /data/redis/member-6379/conf/redis.conf
启动后查看一下进程,另外看一下日志信息,可能会报有如下信息:
# WARNING: The TCP backlog setting of 65535 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 1024. # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot.
可以看到一共有三个警告信息:
第一个WARNING:somaxconn值太小,一般设置为65535.
somaxconn文件定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128。对于一个TCP连接,Server与Client需要通过三次握手来建立网络连接。当三次握手成功后,我们可以看到端口的状态由LISTEN转变为ESTABLISHED,接着这条链路上就可以开始传送数据了。每一个处于监听(Listen)状态的端口,都有自己的监听队列。
对于一个经常处理新连接的高负载服务环境来说,默认的128太小了。大多数环境这个值建议增加到1024或者更多。服务进程会自己限制侦听队列的大小(例如redis),常常在它们的配置文件中有设置队列大小的选项。大的侦听队列对防止拒绝服务DoS攻击也会有所帮助。
第二个WARNING:overcommit_memory值为0,可以设置为1.
overcommit_memory文件指定了内核针对内存分配的策略,其值可以是0、1、2。
0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2:表示内核允许分配超过所有物理内存和交换空间总和的内存。
第三个WARNING:hugepage默认开启,可以选择关闭.
hugepage是Linux内存管理中提供大内存页的一种称呼,目前对于大内存应用的服务都是建议关闭的,如MySQL、MongoDB、Oracle等数据库。对于hugepage可以看这篇文章“hugepage详解”。
转载自:运维那点事