Redis简介
**
Redis是一款开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存数据结构存储系统、可以用作数据库、缓存和消息中间件等。Redis有以下特点:
- 支持不同级别的磁盘持久化,可以将内存中的数据保存在磁盘中,重启可再次加载使用。
- 支持多种类型的数据结构,如字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)与范围查询,bitmaps,hyperloglogs和地理空间(geospatial)索引半径查询等数据结构的存储。
- 支持数据的备份,即Master-Slave模式的数据备份。
- 读速度为110000次/s,写速度为81000次/s,性能极高。
- Redis所有操作都是原子的,意思是要么成功执行要么失败完全不执行。
- Redis内置了事务(transactions)功能,支持多个操作也支持事务。
- Redis内置了LRU驱动事件(LRU eviction),支持key过期处理。
- Redis支持publish/subscribe、notify等。
Redis基本配置
**
基本配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
daemonize | Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程。 用守护进程后,Redis会把pid写到一个pidfile中,在/var/run/redis.pid |
no |
port | Redis访问端口,由于Redis是单线程模型,因此单机开多个Redis进程的时候会修改端口。 如果指定0端口,表示Redis不监听TCP连接 |
6379 |
bind | 当配置了bind之后: - 只有bind指定的ip可以直接访问Redis,这样可以避免将Redis服务暴露于危险的网络环境中,防止一些不安全的人随随便便通过远程访问Redis - 如果bind选项为空或0.0.0.0的话,那会接受所有来自于可用网络接口的连接 |
127.0.0.1 |
protected-mode | protected-mode是Redis3.2之后的新特性,用于加强Redis的安全管理,当满足以下两种情况时,protected-mode起作用: - bind未设置,即接收所有来自网络的连接 - 密码未设置 |
当满足以上两种情况且protected-mode=yes的时候,访问Redis将报错,即密码未设置的情况下,无密码访问Redis只能通过安装Redis的本机进行访问。 | yes |
| tcp-backlog(重要)链接 | 半连接队列的大小 | 511 |
| timeout | 当客户端闲置多长时间后关闭连接,0表示不管 | 0 |
| tcp-keepalive | 指定TCP连接是否为长连接, ACKs信号由server端维护,长连接将会额外的增加server端的开支。
默认为0.表示禁用,非0值表示开启 长连接 ;ACKs信号的发送间隔将有linux系统决定。
在多次ACKs后,如果对等端仍不回复,将会关闭连接,否则连接将会被保持开启。
client端socket也可以通过配置keepalive选项,开启长连接。 | 300 |
| loglevel | # 指定日志记录级别,生产环境推荐 notice
# Redis 总共支持四个级别: debug 、 verbose 、 notice 、 warning ,默认为 verbose
# debug 记录很多信息,用于开发和测试
# varbose 有用的信息,不像 debug 会记录那么多
# notice 普通的 verbose ,常用于生产环境
# warning 只有非常重要或者严重的信息会记录到日志 | notice |
| logfile | 指定Redis日志记录方式,默认值为stdout,表示打印在命令行终端的窗口上,也可设为/dev/null屏蔽日志 | |
| databases | 设定redis所允许的最大”db簇”(可以理解为数据库)的个数,默认为16个簇.
客户端可以通过”select”指令指定需要使用的”db簇”索引号,默认为0.
redis的顶层数据结构中,所有K-V都潜在的包括了”db簇”索引号,任何一个key都将隶属于一个”db簇”.
任何对数据的检索,只会覆盖指定的”db簇”;例如数据被插入到”db 10″中,那么在”db 1”中去get,将会返回null.
对数据归类到不同的db簇中,可以帮助我们实现一些特定的需求,比如根据不同客户端连接,来指定不同的db索引号. | 16 |
Redis快照配置参数
快照配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
save | 保存数据到磁盘 指出在多长时间内,有多少次更新操作,就将数据同步到数据文件dump.rdb中。 相当于条件触发抓取快照,这个可以多个条件配合 比如默认配置文件中的设置,就设置了三个条件 save “” #用来禁用snapshot功能 save 900 1 #900 秒内至少有 1 个 key 被改变 save 300 10 #300 秒内至少有10 个 key 被改变 save 60 10000 #60 秒内至少有 10000 个 key 被改变 |
save 900 1 save 300 10 save 60 10000 |
stop-writes-on-bgsave-error | 当启用了RDB且后台保存数据失败,Redis是否停止接收数据。 如果Redis重启了,那么又可以重新开始接收数据了 |
yes |
rdbcompression | 是否启用rdb文件压缩手段,默认为yes. 使用LZF压缩字符串,可能需要额外的cpu开支,不过这能够有效的减小rdb文件的大小,有利于存储/备份/传输/数据恢复 |
yes |
rdbchecksum | 是否校验RDB文件,是否对rdb文件使用CRC64校验和,默认为”yes”,那么每个rdb文件内容的末尾都会追加CRC校验和. 对于其他第三方校验工具,可以很方便的检测文件的完整性,耗费CPU资源。 |
yes |
dbfilename | 本地持久化数据库文件名,默认值为 dump.rdb | dump.rdb |
dir | 工作目录 指定rdb/AOF文件的目录位置,只能为文件夹不能为文件 数据库镜像备份的文件放置的路径。 这里的路径跟文件名要分开配置是因为 redis 在进行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成,再把该临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放在这个指定的路径当中。 注意这里必须制定一个目录而不是文件 |
/var/lib/redis-server/ |
Redis主从复制配置
**
主从复制配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
replicaof | 主从复制 . 设置该数据库为其他数据库的从数据库 . replicaof 设置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步 |
关闭 |
masterauth | 以认证的方式连接到master。 如果master中使用了requirepass配置进行密码保护,slave必须交付正确的授权密码,才能连接成功。 “requirepass”配置项指定了当前server的密码。 此配置项中值需要和master机器的”requirepass”保持一致 |
关闭 |
replica-serve-stale-data | 如果当前server是replica,那么当replica与master失去通讯时,是否继续为客户端提供服务: - 设置为 yes( 默认设置 ) ,lave继续向客户端提供只读服务,有可能此时的数据已经过期。 - 设置为 no ,除INFO 和 SLAVOF 命令之外的任何请求都会返回一个 错误 “SYNC with master in progress”。 |
yes |
replica-read-only | 配置Redis的replica实例是否接受写操作,即replica是否为只读Redis | yes |
repl-ping-slave-period | 从库会按照一个时间间隔向主库发送 PINGs. 可以通过 repl-ping-slave-period 设置这个时间间隔,默认是 10 秒 | 10 秒 |
repl-timeout | 设置主库批量数据传输时间或者 ping 回复时间间隔,默认值是 60 秒 | 60 秒 |
repl-disable-tcp-nodelay | - yes,Redis将使用一个较小的数字TCP数据包和更少的带宽将数据发送到replica,但是这可能导致数据发送到replica端会有延迟 , 如果是 Linux kernel 的默认配置,会达到 40 毫秒 . - no,则发送数据到 replica端的延迟会降低,但将使用更多的带宽用于复制 |
no |
repl-backlog-size | 设置复制的后台日志大小。 - 复制的后台日志越大, replica 断开连接及后来可能执行部分复制花的时间就越长。 - 后台日志在至少有一个 replica 连接时,仅仅分配一次。 |
1mb |
repl-backlog-ttl | 在 master 不再连接 replica后,后台日志将被释放。下面的配置定义从最后一个 replica断开连接后需要释放的时间(秒)。 0 意味着从不释放后台日志 |
3600 |
replica-priority | 如果 master 不能再正常工作,那么会在多个 replica 中,选择优先值最小的一个 replica提升为 master ,优先值为 0 表示不能提升为 master 。 | 100 |
min-slaves-to-write | 如果少于 N 个 slave 连接,且延迟时间 <=M 秒,则 master 可配置停止接受写操作 | |
min-slaves-max-lag |
Redis安全配置
**
安全配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
requirepass | 设置客户端连接后进行任何其他指定前需要使用的密码。 警告:因为 redis 速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行 150K 次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解 |
关闭 |
rename-command | 命令重命名,对于一些危险命令例如: - flushdb(清空数据库) - flushall(清空所有记录) - config(客户端连接后可配置服务器) - keys(客户端连接后可查看所有存在的键) |
作为服务端redis-server,常常需要禁用以上命令来使得服务器更加安全,禁用的具体做法是是:
- rename-command FLUSHALL “”
也可以保留命令但是不能轻易使用,重命名这个命令即可:
- rename-command FLUSHALL abcdefg
这样,重启服务器后则需要使用新命令来执行操作,否则服务器会报错unknown command
如果想删除一个命令,直接把它重命名为一个空字符 “” 即可,
如:rename-command CONFIG “” | 关闭 |
Redis内存管理配置
**
内存管理配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
maxmemory | 指定 Redis 最大内存限制, Redis 在启动时会把数据加载到内存中,达到最大内存后,如果开启时 Redis 会按照清除策略尝试清除已到期的 Key。 如果 Redis 依照策略清除后无法提供足够空间,或者策略设置为 ”noeviction” ,则使用更多空间的命令将会报错,例如 SET, LPUSH 等。但仍然可以进行读取操作 注意: Redis 新的 vm 机制,会把 Key 存放内存, Value 会存放在 swap 区 |
关闭 |
maxmemory-policy | 当达到了maxmemory之后Redis移除数据,有8种方式可供选择: - volatile-lru,使用LRU算法,移除设置了过期时间的 key - allkeys-lru,根据LRU算法,移除范围为所有的key - volatile-lfu:使用LFU算法,移除设置了过期时间的 key - allkeys-lfu:使用LFU算法,移除范围为所有的key - volatile-random,使用随机算法,移除范围为设置了过期时间的 key - allkeys-random,使用随机算法,移除范围为所有的key - volatile-ttl,移除设置了过期时间的 key中最近的要过期的数据 - noeviction,不过期,当写操作的时候返回错误 |
注意,当写操作且Redis发现没有合适的数据可以移除的时候,将会报错 | noeviction |
maxmemory-policy :
redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
volatile-lfu:从已设置过期时间的数据集(server.db[i].expires)中挑选使用频率最少的数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
allkeys-lfu:从数据集(server.db[i].dict)中挑选使用频率最少的数据淘汰
no-enviction(驱逐):禁止驱逐数据,当写操作的时候返回错误
Redis懒删除配置
懒删除配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
lazyfree-lazy-eviction | 内存满逐出 | no |
lazyfree-lazy-expire | 过期key删除 | no |
lazyfree-lazy-server-del | 内部删除,比如rename oldkey newkey时,如果newkey存在需要删除newkey | no |
replica-lazy-flush | 接收完RDB文件后清空数据选项 | no |
Redis持久化配置
(APPEND ONLY MODE)AOF配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
appendonly | 默认情况下, redis 会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。 所以 redis 提供了另外一种更加高效的数据库备份及灾难恢复方式。 开启 append only 模式之后, redis 会把所接收到的每一次写操作请求都追加到 appendonly.aof 文件中,当 redis 重新启动时,会从该文件恢复出之前的状态,先忽略RDB文件。 但是这样会造成 appendonly.aof 文件过大,所以 redis 还支持了 BGREWRITEAOF 指令,对 appendonly.aof 进行重新整理。 你可以同时开启 asynchronous dumps 和 AOF |
关闭 |
appendfilename | AOF文件名称 | appendonly.aof |
appendfsync | 操作系统实际写数据到磁盘的频率,有以下几个选项: - always,每次有写操作都进行同步,慢,但是最安全 - everysec,对写操作进行累积,每秒同步一次,是一种折衷方案 - no,当操作系统flush缓存的时候同步,性能更好但是会有数据丢失的风险 |
当不确定是使用哪种的时候,官方推荐使用everysec,它是速度与数据安全之间的一种折衷方案 | everysec |
| no-appendfsync-on-rewrite | aof持久化机制有一个致命的问题,随着时间推移,aof文件会膨胀,当server重启时严重影响数据库还原时间,因此系统需要定期重写aof文件。
重写aof的机制为bgrewriteaof,即在一个子进程中重写从而不阻塞主进程对其他命令的处理,但是这依然有个问题。
bgrewriteaof和主进程写aof,都会操作磁盘,而bgrewriteaof往往涉及大量磁盘操作,这样就会让主进程写aof文件阻塞。
针对上述问题,可以使用此时可以使用no-appendfsync-on-rewrite参数做一个选择:
- no,最安全,不丢失数据,但是需要忍受阻塞
- yes,数据写入缓冲区,不造成阻塞,但是如果此时redis挂掉就会丢失数据,在Linux操作系统默认设置下,最坏场景下会丢失30秒数据
| no |
| auto-aof-rewrite-percentage | 当 AOF 文件增长到一定大小的时候 Redis 能够调用 BGREWRITEAOF 对日志文件进行重写
# 它是这样工作的: Redis 会记住上次进行些日志后文件的大小 ( 如果从开机以来还没进行过重写,那大小在开机的时候确定 )
# 本次aof文件超过上次aof文件该值的百分比时,重写功能将启动
# 同时需要指定一个最小值用于 AOF 重写,用于阻止即使文件很小但是增长幅度很大也去重写 AOF 文件的情况
# 设置 percentage 为 0 就关闭这个特性 | 100 |
| auto-aof-rewrite-min-size | aof文件最小值,只有到达这个值才会触发rewrite,即rewrite由auto-aof-rewrite-percentage+auto-aof-rewrite-min-size共同保证 | 64mb |
| aof-load-truncated | redis在以aof方式恢复数据时,对最后一条可能出问题的指令的处理方式:
- yes,log并继续
- no,直接恢复失败
| yes |
Redis集群配置
集群配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
cluster-enabled | 正常来说Redis实例是无法称为集群的一部分的,只有以集群方式启动的节点才可以。为了让Redis以集群方式启动,就需要此参数。 | yes |
cluster-config-file | 每个集群节点应该有自己的配置文件,这个文件是不应该手动修改的,它只能被Redis节点创建且更新,每个Redis集群节点需要不同的集群配置文件 | 关闭,nodes-6379.conf |
cluster-node-timeout | 集群中一个节点向其他节点发送ping命令时,必须收到回执的毫秒数 | 关闭,15000 |
cluster-slave-validity-factor | 如果该项设置为0,不管Slave节点和Master节点间失联多久都会一直尝试failover。 比如timeout为5,该值为10,那么Master与Slave之间失联50秒,Slave不会去failover它的Master |
关闭,10 |
cluster-migration-barrier | 当一个Master拥有多少个好的Slave时就要割让一个Slave出来。 例如设置为2,表示当一个Master拥有2个可用的Slave时,它的一个Slave会尝试迁移 |
关闭,1 |
cluster-require-full-coverage | 有节点宕机导致16384个Slot全部被覆盖,整个集群是否停止服务,这个值一定要改为no | 关闭,yes |
Redis慢查询日志配置
慢查询日志配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
slowlog-log-slower-than | Redis Slow Log 记录超过特定执行时间的命令。执行时间不包括 I/O 计算比如连接客户端,返回结果等,只是命令执行时间 # 可以通过两个参数设置 slow log :一个是告诉 Redis 执行超过多少时间被记录的参数 slowlog-log-slower-than( 微妙 ) , # 另一个是 slow log 的长度。当一个新命令被记录的时候最早的命令将被从队列中移除 # 时间以微妙为单位,因此 1000000 代表一秒。 # 注意指定一个负数将关闭慢日志,而设置为 0 将强制每个命令都会记录 |
1000000 |
slowlog-max-len | 对日志长度没有限制,只是要注意它会消耗内存 可以通过 SLOWLOG RESET 回收被慢日志消耗的内存 推荐使用默认值 128 ,当慢日志超过 128 时,最先进入队列的记录会被踢出 |
128 |
Redis事件通知配置
时间通知配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
notify-keyspace-events | # 当事件发生时, Redis 可以通知 Pub/Sub 客户端。 # 可以在下表中选择 Redis 要通知的事件类型。事件类型由单个字符来标识: # K Keyspace 事件,以 keyspace@ 的前缀方式发布 # E Keyevent 事件,以 keysevent@ 的前缀方式发布 # g 通用事件(不指定类型),像 DEL, EXPIRE, RENAME, … # $ String 命令 # s Set 命令 # h Hash 命令 # z 有序集合命令 # x 过期事件(每次 key 过期时生成) # e 清除事件(当 key 在内存被清除时生成) # A g$lshzxe 的别称,因此 ”AKE” 意味着所有的事件 # notify-keyspace-events 带一个由 0 到多个字符组成的字符串参数。空字符串意思是通知被禁用。 # 例子:启用 list 和通用事件: # notify-keyspace-events Elg # 默认所用的通知被禁用,因为用户通常不需要改特性,并且该特性会有性能损耗。 # 注意如果你不指定至少 K 或 E 之一,不会发送任何事件。 |
“” |
Redis高级特性配置
高级特性配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
hash-max-zipmap-entries | hash 中包含超过指定元素个数并且最大的元素没有超过临界时, # hash 将以一种特殊的编码方式(大大减少内存使用)来存储,这里可以设置这两个临界值 # Redis Hash 对应 Value 内部实际就是一个 HashMap ,实际这里会有 2 种不同实现, # 这个 Hash 的成员比较少时 Redis 为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的 HashMap 结构,对应的 valueredisObject 的 encoding 为 zipmap, # 当成员数量增大时会自动转成真正的 HashMap, 此时 encoding 为 ht 。 |
512 |
hash-max-zipmap-value | 64 | |
list-max-ziplist-entries | 和 Hash 一样,多个小的 list 以特定的方式编码来节省空间。 # list 数据类型节点值大小小于多少字节会采用紧凑存储格式。 |
512 |
list-max-ziplist-value | 64 | |
set-max-intset-entries | set 数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储 | 512 |
zset-max-ziplist-entries | 和 hashe 和 list 一样 , 排序的 set 在指定的长度内以指定编码方式存储以节省空间 # zsort 数据类型节点值大小小于多少字节会采用紧凑存储格式。 |
512 |
zset-max-ziplist-value | 64 | |
activerehashing | Redis 将在每 100 毫秒时使用 1 毫秒的 CPU 时间来对 redis 的 hash 表进行重新 hash ,可以降低内存的使用 # 当你的使用场景中,有非常严格的实时性需要,不能够接受 Redis 时不时的对请求有 2 毫秒的延迟的话,把这项配置为 no 。 # 如果没有这么严格的实时性要求,可以设置为 yes ,以便能够尽可能快的释放内存 |
yes |
client-output-buffer-limit | # 客户端的输出缓冲区的限制,因为某种原因客户端从服务器读取数据的速度不够快, # 可用于强制断开连接(一个常见的原因是一个发布 / 订阅客户端消费消息的速度无法赶上生产它们的速度)。 # 可以三种不同客户端的方式进行设置: # normal -> 正常客户端 # slave -> slave 和 MONITOR 客户端 # pubsub -> 至少订阅了一个 pubsub channel 或 pattern 的客户端 # 每个 client-output-buffer-limit 语法 : # client-output-buffer-limit # 一旦达到硬限制客户端会立即断开,或者达到软限制并保持达成的指定秒数(连续)。 # 例如,如果硬限制为 32 兆字节和软限制为 16 兆字节 /10 秒,客户端将会立即断开 # 如果输出缓冲区的大小达到 32 兆字节,客户端达到 16 兆字节和连续超过了限制 10 秒,也将断开连接。 # 默认 normal 客户端不做限制,因为他们在一个请求后未要求时(以推的方式)不接收数据, # 只有异步客户端可能会出现请求数据的速度比它可以读取的速度快的场景。 # 把硬限制和软限制都设置为 0 来禁用该特性 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb60 client-output-buffer-limit pubsub 32mb 8mb60 |
|
hz | Redis 服务器执行后台任务的频率。如:关闭客户端超时的连接,清除过期的 Key。默认为10,此值越大表示redis对后台任务的执行次数越频繁(次数/秒) 此值过小意味着更多的cpu周期消耗,后台任务被轮询的次数更频繁 此值过大意味着”内存敏感”性较差. 建议保持默认值 |
10 |
aof-rewrite-incremental-fsync | aof rewrite过程中,是否采取增量”文件同步”策略,默认为”yes”,而且必须为yes. rewrite过程中,每32M数据进行一次文件同步,这样可以减少”aof大文件”写入对磁盘的操作次数。 |
yes |
Redis碎片整理配置
高级特性配置 | ||
---|---|---|
配置 | 作用 | 默认值 |
activedefrag | #启用主动碎片整理 | |
yes | ||
active-defrag-ignore-bytes | 启动活动碎片整理的最小碎片浪费量 | 100mb |
active-defrag-threshold-lower | 启动碎片整理的最小碎片百分比 | 10 |
active-defrag-threshold-upper | 使用最大消耗时的最大碎片百分比 | 100 |
active-defrag-cycle-min | 在CPU百分比中进行碎片整理的最小消耗 | 5 |
active-defrag-cycle-max | 磁盘碎片整理的最大消耗 | 75 |
active-defrag-max-scan-fields | 将从主字典扫描处理的最大set / hash / zset / list字段数 | 1000 |
Redis性能测试
之前说过Redis在make之后有一个redis-benchmark,这个就是Redis提供用于做性能测试的,它可以用来模拟N个客户端同时发出M个请求。首先看一下redis-benchmark自带的一些参数:
参数 | 作用 | 默认值 |
---|---|---|
-h | 服务器名称 | 127.0.0.1 |
-p | 服务器端口 | 6379 |
-s | 服务器Socket | 无 |
-c | 并行连接数 | 50 |
-n | 请求书 | 10000 |
-d | SET/GET值的字节大小 | 2 |
-k | 1表示keep alive,0表示重连 | 1 |
-r | SET/GET/INC使用随机Key而不是常量,在形式上key样子为mykey_ran:000000012456 -r的值决定了value的最大值 |
无 |
-p | 使用管道请求 | 1,即不使用管道 |
-q | 安静模式,只显示query/sec值 | 无 |
—csv | 使用csv格式输出 | 无 |
-l | 循环,无限运行测试 | 无 |
-t | 只运行使用逗号分割的命令的测试 | 无 |
-I | 空闲模式,只打开N个空闲线程并且等待 | 无 |