Redis介绍
(REmote DIctionary Server 远程字典服务器) Redis是一个使用C编写的、开源的、Key-Value型、基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一。
Redis和其它数据库或缓存服务器的对比
Redis基础知识
单进程
Redis的服务器程序采用的是单进程模型来处理客户端的请求。
对读写等事件的响应是通过对epoll函数的包装来做到的。
Redis的实际处理速度完全依靠主进程的执行效率,假如同时有多个客户端并发访问服务器,则服务器处理能力在一定情况下将会下降。
假如你要提升服务器的并发能力,那么可以采用在单台机器部署多个redis进程的方式。
多数据库
1:Redis每个数据库对外都是以从0开始递增的数字来命名,默认16个数据库,默认使用0号数据库,可以使用Select 数字来选择要使用的数据库
2:使用Dbsize可以查看当前数据库的key的数量
3:可以在多个数据库间移动数据,使用move key 目的数据库编号就可以了
4:使用flushdb可以清除某个数据库的数据
5:Redis不支持自定义数据库名字
6:Redis不支持为每个数据库设置不同的访问密码
7:多个数据库之间并不是完全独立的,FlushAll可以清空全部的数据
8:Redis的数据库更像是一个命名空间
Redis的数据类型
Redis的key
Redis的key是字符串类型,如果中间有空格或者转义字符等,要用“”。
1:命名建议:对象类型:对象ID:对象属性
2:多个单词之间以“.”来分隔
3:Key的命名,应该在可读的情况下,尽量简短
Redis的Value支持五种类型
1:String:字符串,可以存储String、Integer、Float型的数据,甚至是二进制数据,一个字符串最大容量是512M
2:List:字符串List,底层实现上不是数组,而是链表,也就是说在头部和尾部插入一个新元素,其时间复杂度是常数级别的;其弊端是:元素定位比数组慢
3:Set:字符串Set,无序不可重复,是通过HashTable实现的
4:Hash:按Hash方式来存放字符串
5:ZSet:字符串Set,有序且不可重复,根据Score来排序。底层使用散列表和跳跃表来实现,所以读取中间部分数据也很快
Redis的基本操作
对Keys的操作命令
1:Keys:获得符合规则的键名列表
格式是keys pattern,pattern支持glob风格通配符格式:
(1)? 匹配一个字符
(2)* 匹配任意个字符
(3)[] 匹配中括号内的任一字符,可以用-来表示一个范围
(4)\x 匹配字符x,用于转义符号
2:exists:判断键值是否存在,格式是exists key
3:del:删除key,格式是del key。
小技巧:Del命令不支持通配符,可以结合linux管道和xargs命令来自定义删除,示例如下:redis-cli keys k* | xargs redis-cli del
4:type:获得键值的数据类型,格式是type key
5:rename:改名,格式是rename oldKey newKey
6:renamenx:如果不存在则改名,格式是rename oldKey newKey
对String类型的操作命令
1:get、set、del:获取key的值、设置key和值、删除key
2:incr、decr:递增和递减整数值,格式是incr key值
3:incrby、decrby:递增和递减整数值,可指定增减的数值,格式是incrby key值 正负数值 4:incrbyfloat:递增和递减浮点数值,格式是incrbyfloat key值 正负数值
5:append:在尾部追加值,格式是append key值 追加的值
6:getrange:获取指定索引范围内的值,格式是getrange key值 起始索引 结束索引
7:setrange:从索引位置开始设置后面的值,格式是setrange key值 offset索引 值
8:strlen:返回键值的长度,格式是strlen key值
9:mget:同时获得多个键的值,格式是mget 多个key值
10:mset:同时设置多个键值对,格式是mset key值 value , key和value可以多对
11:bitcount:获取范围内为1的二进制位数,格式是bitcount key值 [start end]
12:getbit:获取指定位置的二进制位的值,格式是getbit key值 offset索引
13:setbit:设置指定位置的二进制位的值,格式是setbit key值 offset索引值
14:bitop:对多个二进制值进行位操作,格式是bitop 操作 目的key key值1 key值2,操作有and、or、
xor、not,key值可以是多个
15:getset:原子的设置key的值,并返回key的旧值 ,格式是getset key value
对List类型的操作命令
1:lpush/rpush:添加值,格式是 rpush list的key item项的值,值可以是多个
2:lrange:按索引范围获取值,格式是 lrange list的key 起始索引 终止索引,-1表示最后一个索引 3:lindex:获取指定索引的值,格式是 lindex list的key 索引号
4:lpop/rpop:弹出值,格式是 lpop list的key
5:llen:获取元素个数,格式是llen list的key
6:lrem:删除元素,格式是lrem list的key 数量 item项的值,数量可正负,表示从左或右删除,如果数
量为0,表示删除全部与给定值相等的项
7:ltrim:保留指定索引区间的元素,格式是ltrim list的key 起始索引 结束索引
8:blpop/brpop:弹出值,格式是blpop list的key值 过期时间,key可以是多个,如果没有值,会一值等
待有值,直到过期
9:rpoplpush:将元素从一个列表转移到另外一个列表,格式是rpoplpush 源list的key值 目的list的key
值
10:brpoplpush:将元素从一个列表转移到另外一个列表,格式是brpoplpush 源list的key值 目的list的
key值 过期时间
11:lset:设置指定索引的值,格式是lset list的key 索引 新的值
12:linsert:插入元素,格式是linsert list的key before|after 定位查找的值 添加的值
对Set类型的操作命令
1:sadd:添加元素,格式是 sadd set的key item项的值,item项可以多个
2:smembers:获取集合中所有元素,格式是 smembers set的key
3:sismember:判断元素是否在集合众,格式是 sismember set的key item项的值
4:srem:删除元素,格式是 srem set的key item项的值
5:scard:获取集合中元素个数,格式是scard set的key
6:srandmember:随机获取集合中的元素,格式是srandmember set的key [数量],数量为正的时候,会随
机获取这么多个不重复的元素;如果数量大于集合元素个数,返回全部;如果数量为负,会随机获得这
么多个元素,可能有重复
7:spop:弹出元素,格式是spop set的key
8:smove:移动元素,格式是smove 源set的key 目的set的key item项的值
9:sdiff:差集,返回在第一个set里面而不在后面任何一个set里面的项,格式是sdiff set的key 用来比
较的多个set的key
10:sdiffstore:差集并保留结果,格式是命令 存放结果的set的key set的key 用来比较的多个set的key 11:sinter:交集,返回多个set里面都有的项,格式是sinter 多个set的key
12:sinterstore:交集并保留结果,格式是sinter 存放结果的set的key 多个set的key
13:sunion:并集,格式是sunion 多个set的key
14:sunionstore:并集并保留结果,格式是sunionstore 存放结果的set的key 多个set的key
对Hash类型的操作命令
1:hset:设置值,格式是hset Hash的Key 项的key 项的值
2:hmset:同时设置多对值,格式是hmset Hash的Key 项的key 项的值,项的key和值可多对
3:hgetall:获取该Key下所有的值,格式是hgetall Hash的Key
4:hget:获取值,格式是hget Hash的Key 项的key 5:hmget:同时获取多个值,格式是hmget Hash的Key 项的key,项的key可以是多个
6:hdel:删除某个项,格式是hdel Hash的Key 项的key
7:hlen:获取Key里面的键值对数量,格式是hlen Hash的Key
8:hexists:判断键值是否存在,格式是hexists Hash的Key 项的key
9:hkeys:获取所有Item的key,格式是hkeys Hash的Key
10:hvals:获取所有Item的值,格式是hvals Hash的Key
11:hincrby:增减整数数字,格式是hincrby Hash的Key 项的key 正负整数
12:hincrbyfloat:增减Float数值,格式是hincrbyfloat Hash的Key 项的key 正负float
13:hsetnx:如果项不存在则赋值,存在时什么都不做,格式是hsetnx Hash的Key 项的 key 项的值
对ZSet类型的操作命令
1:zadd:添加元素,格式是zadd zset的key score值 项的值,Score和项可以是多对,score可以是整数,
也可以是浮点数,还可以是+inf表示正无穷大,-inf表示负无穷大
2:zrange:获取索引区间内的元素,格式是zrange zset的key 起始索引 终止索引 (withscores) 3:zrangebyscore:获取分数区间内的元素,格式是zrangebyscore zset的key 起始score 终止score
(withscores),默认是包含端点值的,如果加上“(”表示不包含;后面还可以加上limit来限制
4:zrem:删除元素,格式是zrem zset的key 项的值,项的值可以是多个
5:zcard:获取集合中元素个数,格式是zcard zset的key
6:zincrby:增减元素的Score,格式是zincrby zset的key 正负数字项的值
7:zcount:获取分数区间内元素个数,格式是zcount zset的key 起始score 终止score
8:zrank:获取项在zset中的索引,格式是zrank zset的key 项的值
9:zscore:获取元素的分数,格式是zscore zset的key 项的值,返回项在zset中的score
10:zrevrank:获取项在zset中倒序的索引,格式是zrevrank zset的key 项的值
11:zrevrange:获取索引区间内的元素,格式是zrevrange zset的key 起始索引 终止索引 (withscores) 12:zrevrangebyscore:获取分数区间内的元素,格式是zrevrangebyscore zset的key 终止score 起始
score (withscores)
13:zremrangebyrank:删除索引区间内的元素,格式是zremrangebyrank zset的key 起始索引 终止索引 14:zremrangebyscore:删除分数区间内的元素,格式是命令 zset的key 起始score 终止score
15:zinterstore:交集,格式是ZINTERSTORE dest-key key-count key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
16:zunionstore:并集,格式是ZUNIONSTORE dest-key key-count key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
排序
1:sort:可以对List、Set、ZSet里面的值进行排序。格式是SORT source-key [BY pattern] [LIMIT
offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE dest-key]
2:by:设置排序的参考键,可以是字符串类型或者是Hash类型里面的某个Item键,格式是 Hash键名:*-
>Item键。设置了by参考键,sort将不再依据元素的值来排序,而是对每个元素,使用元素的值替换参 考键中的第一个”*”,然后获取相应的值,再对获得的值进行排序。
如果参考键不存在,默认为0。
如果参考键值一样,再以元素本身的值进行排序。
3:get:指定sort命令返回结果包含的键的值,形如: Hash键名:*->Item键,可以指定多个get,返回的时
候,一行一个。如果要返回元素的值,用get #。
4:对较大数据量进行排序会严重影响性能,
使用建议:
(1)尽量减少待排序集合中的数据
(2)使用limit来限制获取的数据量
(3)如果要排序的数据量较大,可以考虑使用Store参数来缓存结果
处理过期keys的机制 当client主动访问key时,会先对key进行超时判断,过时的key会立刻删除;另外
Redis会在后台,每秒10次的执行如下操作: 随机选取100个key校验是否过期,如果有25 个以上的key过期了,立刻额外随机选取下100个key(不计算在10次之内)。也就是说,如果 过期的key不多,Redis最多每秒回收200条左右,如果有超过25%的key过期了,它就会做得 更多,这样即使从不被访问的数据,过期了也会被删除掉。
n 处理过期keys的命令
1:expire:设置过期时间,格式是expire key值 秒数
2:expireat:设置过期时间,格式是expireat key值 到秒的时间戳
3:ttl:查看还有多少秒过期,格式是ttl key值,-1表示永不过期,-2表示已过期
4:persist:设置成永不过期,格式是persist key值,删除key的过期设置;另外使用set或 者getset命令为键赋值的时候,也会清除键的过期时间
5:pttl:查看还有多少毫秒过期,格式是pttl key值
6:pexpire:设置过期时间,格式是pexpire key值 毫秒数
7:pexpireat:设置过期时间,格式是pexpireat key值 到毫秒的时间戳
Redis的配置详解
Config命令
可以在redis-cli里面使用config命令来获取或者设置Redis配置,可以不用重新启动Redis。
命令是config get/set 配置名。注意并不是所有的配置参数都可以通过Config来在运行期修改,
比如: daemonize、pidfile、port、database、dir、slaveof、rename-command等
redis.conf的配置介绍
1:开头定义了一些基本的度量单位,只支持bytes,不支持bit
2:配置中对单位的大小写不敏感
3:配置中大致包含如下部分:
(1)通用部分
(2)快照部分:Redis的RDB持久化相关的配置
(3)复制部分
(4)安全部分
(5)限制部分
(6)追加模式部分
(7)LUA脚本部分
(8)慢日志部分
(9)事件通知部分
(10)高级配置部分
通用部分
1:daemonize:是否以后台daemon方式运行
2:pidfile:pid文件位置,默认会生成在/var/run/redis.pid
3:bind:指定要绑定的IP,默认Redis会响应本机所有可用网卡的连接请求
4:port:监听的端口号,默认服务端口是6379,0表示不监听端口;如果redis不监听端口,可以通过unix
socket方式来接收请求,可以通过unixsocket配置项来指定unix socket文件的路径,并通过
unixsocketperm来指定文件的权限
5:tcp-backlog:设置tcp的backlog,backlog其实是一个连接队列,backlog队列总和=未完成三次握手队
列 + 已经完成三次握手队列。在高并发环境下你需要一个高backlog值来避免慢客户端连接问题。注意Linux内核会将这个值减小到/proc/sys/net/core/somaxconn的值,所以需要确认增大somaxconn和 tcp_max_syn_backlog两个值来达到想要的效果
6:timeout:连接空闲超时时间,0表示永不关闭
7:tcp-keepalive:单位为秒,如果设置为0,则不会进行Keepalive检测,建议设置成60
8:loglevel:log信息级别,共分四级,即debug、verbose、notice、warning
9:logfile:log文件位置,如果设置为空字符串,则redis会将日志输出到标准输出。假如你在daemon情况
下将日志设置为输出到标准输出,则日志会被写到/dev/null中
10:syslog-enabled:是否把日志输出到syslog中
11:syslog-ident:指定syslog里的日志标志
12:syslog-facility:指定syslog设备,值可以是USER或LOCAL0-LOCAL7
13:databases:开启数据库的数量,编号从0开始,默认的数据库是编号为0的数据库,可以使用select <DBid>来选择相应的数据库
限制部分
1:maxclients:设置redis同时可以与多少个客户端进行连接。默认情况下为10000个客户端。当你无法设置进程文件句柄限制时,redis会设置为当前的文件句柄限制值减去32,因为redis会为自身内部处理逻辑留一些句柄出来。如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方发出“max number of clients reached”以作回应。
2:maxmemory:设置redis可以使用的内存量。一旦到达内存使用上限,redis将会试图移除内部数据,移除规则可以通过maxmemory-policy来指定。如果redis无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,那么redis则会针对那些需要申请内存的指令返回错误信息,比如SET、LPUSH等。但是对于无内存申请的指令,仍然会正常响应,比如GET等。
如果你的redis是主redis(说明你的redis有从redis),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素
3:maxmemory-samples:设置样本数量,LRU算法和最小TTL算法都并非是精确的算法,而是估算值, 所以你可以设置样本的大小,redis默认会检查这么多个key并选择其中LRU的那个
4:maxmemory-policy:设置内存移除规则,
redis提供了多达6种的移除规则:
(1)volatile-lru:使用LRU算法移除key,只对设置了过期时间的键
(2)allkeys-lru:使用LRU算法移除key
(3)volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键
(4)allkeys-random:移除随机的key
(5)volatile-ttl:移除那些TTL值最小的key,即那些最近要过期的key
(6)noeviction:不进行移除。针对写操作,只是返回错误信息
无论使用上述哪一种移除规则,如果没有合适的key可以移除的话,redis都会针对写请求返回错误信息
快照部分
1:save * *:保存快照的频率,第一个*表示多长时间,单位是秒,第二个*表示至少执行写操作的次数; 在一定时间内至少执行一定数量的写操作时,就自动保存快照;可设置多个条件。 如果想禁用RDB持久化的策略,只要不设置任何save指令,或者给save传入一个空字符串参数也可以
如果用户开启了RDB快照功能,那么在Redis持久化数据到磁盘时如果出现失败,默认情况下, Redis会停止接受所有的写请求。这样做的好处在于可以让用户很明确的知道内存中的数据和磁盘上的 数据已经存在不一致了。如果下一次RDB持久化成功,redis会自动恢复接受写请求。
2:stop-writes-on-bgsave-error:如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制 这种不一致,那么在快照写入失败时,也能确保redis继续接受新的写请求
3:rdbcompression:对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用 LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能
4:rdbchecksum:在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约 10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
5:dbfilename:数据快照文件名(只是文件名,不包括目录),默认dump.rdb
6:dir:数据快照的保存目录(这个是目录),默认是当前路径
追加模式部分
1:appendonly:是否开启AOF
2:appendfilename:设置AOF的日志文件名
3:appendfsync:设置AOF日志如何同步到磁盘,fsync()调用,用来告诉操作系统立即将缓存的指令写入磁
盘,
有三个选项:
(1)always:每次写都强制调用fsync,这种模式下,redis会相对较慢,但数据最安全
(2)everysec:每秒启用一次fsync
(3)no:不调用fsync()。而是让操作系统自行决定sync的时间。这种模式下,redis的性能会最快
4:no-appendfsync-on-rewrite:设置当redis在rewrite的时候,是否允许appendsync。因为redis进程在
进行AOF重写的时候,fsync()在主进程中的调用会被阻止,也就是redis的持久化功能暂时失效。默认
为no,这样能保证数据安全
5:auto-aof-rewrite-min-size:设置一个最小大小,是为了防止在aof很小时就触发重写
6:auto-aof-rewrite-percentage:设置自动进行AOF重写的基准值,也就是重写启动时的AOF文件大小,假 如redis自启动至今还没有进行过重写,那么启动时aof文件的大小会被作为基准值。这个基准值会和当 前的aof大小进行比较。如果当前aof大小超出所设置的增长比例,则会触发重写。
如果设置auto-aof- rewrite-percentage为0,则会关闭此重写功能
复制部分
1:slaveof :指定某一个redis作为另一个redis的从服务器,通过指定IP和端口来设置主redis。建议为从
redis设置一个不同频率的快照持久化的周期,或者为从redis配置一个不同的服务端口
2:masterauth:如果主redis设置了验证密码的话(使用requirepass来设置),则在从redis的配置中要使
用masterauth来设置校验密码,否则的话,主redis会拒绝从redis的访问请求
3:slave-serve-stale-data:设置当从redis失去了与主redis的连接,或者主从同步正在进行中时,redis
该如何处理外部发来的访问请求 。 如果设置为yes(默认),则从redis仍会继续响应客户端的读写请求。如果设置为no,则从 redis会对客户端的请求返回“SYNC with master in progress”,当然也有例外,当客户端发来INFO 请求和SLAVEOF请求,从redis还是会进行处理。从redis2.6版本之后,默认从redis为只读。 4:slave-read-only:设置从Redis为只读
5:repl-ping-slave-period:设置从redis会向主redis发出PING包的周期,默认是10秒
6:repl-timeout:设置主从同步的超时时间,要确保这个时限比repl-ping-slave-period的值要大,否则
每次主redis都会认为从redis超时。
7:repl-disable-tcp-nodelay:设置在主从同步时是否禁用TCP_NODELAY,如果开启,那么主redis 会使用更少的TCP包和更少的带宽来向从redis传输数据。但是这可能会增加一些同步的延迟,大概会达到40毫秒左右。如果关闭,那么数据同步的延迟时间会降低,但是会消耗更多的带宽。
8:repl-backlog-size:设置同步队列长度。队列长度(backlog)是主redis中的一个缓冲区,在与从redis断开连接期间,主redis会用这个缓冲区来缓存应该发给从redis的数据。这样的话,当 从redis重新连接上之后,就不必重新全量同步数据,只需要同步这部分增量数据即可
9:repl-backlog-ttl:设置主redis要等待的时间长度,如果主redis等了这么长时间之后,还是无 法连接到从redis,那么缓冲队列中的数据将被清理掉。设置为0,则表示永远不清理。默认是1 个小时。
10:slave-priority:设置从redis优先级,在主redis持续工作不正常的情况,优先级高的从redis 将会升级为主redis。而编号越小,优先级越高。当优先级被设置为0时,这个从redis将永远也不会被选中。默认的优先级为100。
11:min-slaves-to-write:设置执行写操作所需的最少从服务器数量,如果至少有这么多个从服务器,并且这些服务器的延迟值都少于 min-slaves-max-lag 秒,那么主服务器就会执行客户端 请求的写操作
12:min-slaves-max-lag:设置最大连接延迟的时间, min-slaves-to-write和min-slaves-max-lag 中有一个被置为0,则这个特性将被关闭。默认情况下min-slaves-to-write为0,而min-slaves-max-lag为10
安全部分
当redis-server处于一个不太可信的网络环境中时,可以要求redis客户端在向redis-server发送请求之前,先进行密码验证
1:requirepass:设置请求的密码
2:rename-command:对命令进行重命名,只读的从redis并不适合直接暴露给不可信的客户端。为了尽量降低风险,可以使用rename-command指令来将一些可能有破坏力的命令重命名,避免外部直接调用。
如果要禁用某些命令,那就重命名为“”就可以了
Lua脚本部分
1:lua-time-limit:设置ua脚本的最大运行时间,单位是毫秒,如果此值设置为0或负数,则既不会有报错也不会有时间限制
慢日志部分
1:slowlog-log-slower-than:判断是否慢日志的执行时长,单位是微秒,负数则会禁用慢日志功能,而0则表示强制记录每一个命令
2:slowlog-max-len:慢日志的长度。当一个新的命令被写入日志时,最老的一条会从命令日志队列中被移除。
事件通知部分
1:notify-keyspace-events:设置是否开启Pub/Sub 客户端关于键空间发生的事件,有很多通知的事件类型,默认被禁用,因为用户通常不需要该特性,并且该特性会有性能损耗, 设置成空字符串就是禁用
高级配置部分
1:有关哈希数据结构的一些配置项:当hash只有少量的entry,并且最大的entry所占空间没有超过指定的限制时,会用一种节省内存的数据结构来编码:
(1)hash-max-ziplist-entries:设置使用ziplist的最大的entry数
(2)hash-max-ziplist-value:设置使用ziplist的值的最大长度
2:有关列表数据结构的一些配置项:数据元素较少的list,可以用另一种方式来编码从而节省大量空间:
(1)list-max-ziplist-entries:设置使用ziplist的最大的entry数
(2)list-max-ziplist-value:设置使用ziplist的值的最大长度
3:有关Set数据结构的配置项:当set数据全是十进制64位有符号整型数字构成的字符串时,
设置set使用一种紧凑编码格式来节省内存的最大长度:
(1)set-max-intset-entries:设置使用紧凑编码的最大的entry数
4:有关有序集合数据结构的配置项:有序集合也可以用一种特别的编码方式来节省大量空间,这种编码只适合长度和元素都小于下面限制的有序集合:
(1)zset-max-ziplist-entries:设置使用ziplist的最大的entry数
(2)zset-max-ziplist-value:设置使用ziplist的值的最大长度
5:HyperLogLog 稀疏表示字节限制:这个限制包含了16个字节的头部,当一个HyperLogLog使用sparse representation,超过了这个限制,它就会转换到dense representation上
(1)hll-sparse-max-bytes:设置HyperLogLog 稀疏表示的最大字节数
6:关于是否启用哈希刷新的配置项:启用哈希刷新,每100个CPU毫秒会拿出1个毫秒来刷新 Redis的主哈希表(顶级键值映射表),redis所用的哈希表实现采用延迟哈希刷新机制: 对一个哈希表操作越多,哈希刷新操作就越频繁;反之,如果服务器是空闲的,那么哈希刷新就不会完成,哈希表就会占用更多的一些内存而已。默认是每秒钟进行10次哈希表刷新,用来刷新字典,然后尽快释放内存
(1)activerehashing:设置是否启用哈希刷新,默认是yes
7:有关重写aof的配置项:当一个子进程重写AOF文件时,如果启用下面的选项,则文件每生成32M数据会被同步。为了增量式的写入硬盘并且避免大的延迟,这个指令是非常有用的
(1)aof-rewrite-incremental-fsync:默认是yes
8:关于客户端输出缓冲的控制项:可用于强制断开那些因为某种原因从服务器读取数据的速度不够快的客 户端,一个常见的原因是一个发布/订阅客户端消费消息的速度无法赶上生产它们的速度,可以对三种 不同的客户端设置不同的限制:
(1)normal:正常客户端
(2)slave:slave和 MONITOR 客户端
(3)pubsub:至少订阅了一个pubsub channel或pattern的客户端
语法是:client-output-buffer-limit <class><hard limit> <soft limit> <soft 持续时间单位秒> 默认normal客户端不做限制,因为他们在不主动请求时不接收数据;pubsub和slave客户端会有一个默认值;把硬限制和软限制都设置为0来禁用该功能,默认配置如下:
(1)client-output-buffer-limit normal 0 0 0
(2)client-output-buffer-limit slave 256mb 64mb 60
(3)client-output-buffer-limit pubsub 32mb 8mb 60
9:有关频率的配置项:Redis调用内部函数来执行许多后台任务,Redis依照指定的“hz”值来执行检查任
务,默认情况下,“hz”的被设定为10。提高该值将在Redis空闲时使用更多的CPU时,但同时当有多个 key同时到期会使Redis的反应更灵敏,以及超时可以更精确地处理。范围是1到500之间,但是值超过 100通常不是一个好主意。大多数用户应该使用10这个默认值,只有在非常低的延迟要求时有必要提高 到100
(1)hz:设置检查任务的频率
Redis的持久化
Redis持久化概述
Redis持久化分成两种方式:RDB(Redis DataBase)和AOF(Append Only File)
1:RDB是在不同的时间点,将Redis某一时刻的数据生成快照并存储到磁盘上
2:AOF是只允许追加不允许改写的文件,是将Redis执行过的所有写指令记录下来,在下次 Redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了
3:RDB和AOF两种方式可以同时使用,在这种情况下,如果Redis重启的话,则会优先采用AOF 方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高
4:可以关闭RDB和AOF,这样的话,Redis将变成一个纯内存数据库,就像Memcache一样
5:通过配置redis.conf中的appendonly为yes就可以打开AOF功能
RDB
RDB方式,Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能
如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
RDB的问题
1:fork一个进程时,内存的数据也被复制了,即内存会是原来的两倍
2:每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。
3:由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
触发快照的情况
1:根据配置规则进行自动快照
2:用户执行save或bgsave命令
3:执行flushall命令
4:执行复制replication时
save命令 执行Save命令时,Redis会阻塞所有客户端的请求,然后同步进行快照操作
bgsave命令 执行bgsave命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间。
flushall命令
这个命令会导致Redis清除内存中的所有数据,如果定义了自动快照的条件,那么无论是否满足条件,都会进行一次快照操作;如果没有定义自动快照的条件,那么不会进行快照
AOF
默认的AOF持久化策略是每秒钟fsync一次,fsync是指把缓存中的写指令记录到磁盘中,在这种情况下,Redis仍可以保持很高的性能。当然由于OS会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样 aof方式的持久化也还是有可能会丢失部分修改。不过可以通过配置文件告诉Redis,想要通过fsync函数强制os写入到磁盘的时机。
AOF方式在同等数据规模的情况下,AOF文件要比RDB文件的体积大,因此AOF方式的 恢复速度也要慢于RDB方式。
AOF日志恢复 如果在追加日志时,恰好遇到磁盘空间满或断电等情况,导致日志写入不完整,也没有关系,Redis提供了redis-check-aof工具,可以用来进行日志修复,
基本步骤如下:
1:备份被写坏的AOF文件
2:运行redis-check-aof –fix进行修复
3:用diff -u来看下两个文件的差异,确认问题点
4:重启redis,加载修复后的AOF文件
AOF重写 AOF采用文件追加方式,这会导致AOF文件越来越大,为此,Redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,Redis 就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。可以使用命 令bgrewriteaof
AOF重写的触发机制 Redis是这样工作的:Redis会记录上次重写时的AOF大小。假如自启动至今还没有进
行过重写,那么启动时AOF文件的大小会被作为基准值,这个基准值会和当前的AOF大小进行比较,如果当前AOF大小超出所设置的增长比例,则会触发重写。另外,你还需要设置一个最小大小,是为了防止在AOF很小时就触发重写
AOF重写的基本原理
1:在重写开始前,redis会创建一个“重写子进程”,这个子进程会读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
2:与此同时,主进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。
3:当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中
4:当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中
5:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的 方式重写了一个新的aof文件,这点和快照有点类似
Redis的事务
概述
Redis中的事务就是一组命令的集合,被依次顺序的执行,当然你可以放弃事务的执行,那么所有事务里面的命令都不会执行。
关于Redis的事务有几点说明:
1:Redis的事务仅仅是保证事务里的操作会被连续独占的执行,因为是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的
2:Redis的事务没有隔离级别的概念,因为事务提交前任何指令都不会被实际执行,也就不存 在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这种问题了
3:Redis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
Redis事务的基本过程
1:发送一个事务的命令给Redis,命令是multi
2:依次发送要执行的命令给Redis,Redis接到这些命令,并不会立即执行,而是放到等待执行的事务队列里面
3:发送执行事务的命令给Redis,命令是exec
4:Redis会保证一个事务内的命令依次执行,而不会被其它命令插入
事务过程中的错误处理
1:如果任何一个命令语法有错,Redis会直接返回错误,所有的命令都不会执行
2:如果某个命令执行错误,那么其它的命令仍然会正常执行,然后在执行后返回错误信息
3:Redis不提供事务回滚的功能,开发者必须在事务执行出错后,自行恢复数据库状态
事务操作的基本命令
1:multi:设置事务开始
2:exec:执行事务
3:discard:放弃事务
4:watch:监控键值,如果键值被修改或删除,后面的一个事务就不会执行
5:unwatch:取消watch
Watch说明
1:Redis使用Watch来提供乐观锁定,类似于CAS(Check-and-Set)
2:WATCH 可以被调用多次
3:当 EXEC 被调用后,所有的之前被监视的键值会被取消监视,不管事务是否被取消或者执行。并且当客户端连接丢失的时候,所有东西都会被取消监视
Redis的发布订阅模式
介绍 Redis的发布订阅模式可以实现进程间的消息传递
发布订阅模式的操作命令
1:publish:发布消息,格式是publish channel 消息
2:subscribe:订阅频道,格式是subscribe channel,可以是多个channel
3:psubscribe:订阅频道,格式是psubscribe channel,支持glob风格的通配符
3:unsubscribe:取消订阅,格式是unsubscribe channel,不指定频道表示取消所有subscribe命令的订阅
4:punsubscribe:取消订阅,格式是punsubscribe channel,不指定频道表示取消所有psubscribe命令的订阅,注意这里匹配模式的时候,是不会将通配符展开 的,是严格进行字符串匹配的,比如: punsubscribe * 是无法退定 c1.*的, 必须严格使用punsubscribe c1.*才可以