Redis进阶
一.Redis的优势
1. 大部分主流数据库只支持单一的数据结构,比如传统的关系型数据库只支持二维表格,Memcache只支持字符串的键值对,而Redis支持多种数据结构:字符串,列表,集合,散列,有序集合,HyperLogLog,故此在诸多场景都有应用。
2. 数据存储在内存,读写速度极快。
3. 数据在硬盘有备份,便于故障恢复。
4. 通过Lua脚本可以在服务器端执行用户定义的原子操作。
二. Redis数据结构
1.字符串:用于存储字符,数字,二进制数据,Redis为这几种类型的数据分别定义了不同的操作命令
字符串基本操作:set key value; setnx key value; mset key value[key value....] ;msetnx key value[key value....]; getset key value; append key value; strlen key; setrange key index value; getrange key start end
数字基本操作:incrby key increment; decrby key decrement; incr key; decr key; incrbyfloat key increment
二进制数据基本操作:setbit key index value,bitcount key [start][end]; bitop operation(AND|OR|XOR|NOT) destkey key [key....]
2.散列:用于存储多个键值对,好处是可以将相关的信息放在同一个位置,便于管理;另外,创建键的数量相比直接使用字符串更少,节约内存
基本操作:hset key field value; hsetnx key field value; hexists key field; hdel key field[field...]; hlen ke; hmset key field value[field value...]
hkeys key (返回key包含的所有field); hvals key (返回key包含的所有value); hgetall key(返回key包含的所有field value)
hincrby key field increment; hincrbyfloat key field increment
3.列表:
基本操作:lpush key value[value....] (类似于链表头插法);rpush key value[value....]; llen key; lindex key index; lrange key start stop; lset key index value; linsert key before|after pivot value
lrem key count value (删除count个value);
ltrim key start stop; blpop key[key...] timeout(弹出首个非空列表最左端的项,如果都为空则阻塞直到超时)
示例:可以实现朋友圈时间线功能:当用户发送一条朋友圈消息时,为这条消息分配一个唯一ID,将消息推送到自己的timeline上,并推送到所有朋友的timeline上。
4.集合:无序集合,可以计算并集,交集,差集
基本操作:sadd key element[element...]; srem key element[element...]; sismember key element; scard key(返回集合大小); smembers key(返回集合所有元素,集合过大会造成server阻塞,用sscan代替)
srandmember key [count](返回随机元素); sdiff key[key...] (计算差集); sdiffstore destkey key[key...] (计算差集并存储); sinter key[key...],sunion key[key...]
示例:网站签到
5.有序集合:
示例:同样可以实现时间线,每个用户需要两条时间线,自己的时间线和自己及朋友的时间线。集合中的元素为消息ID,分值为发送时间,用户发送消息时,将新消息的ID和分值用ZADD添加到有序集合里
6.HyperLogLog: 用来做基数(集合中不同元素的数量)统计的算法,优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
介绍:每个键只需要12kb内存,即可存储2^64不同的基数
基本操作:pfadd key element[element]; pfcount key[key...]; pfmerge destkey sourcekey[sourcekey...]
示例:每天网站独立IP个数
三. 持久化
1.RDB持久化:Redis为了提高查询效率,数据都是存储在内存中,同时,为了提高可靠性,Redis提供了两种持久化功能:RDB与AOF,通过这两种方式,Redis将存储在内存中的数据在硬盘中持久化成文件,一旦发生宕机,
重启时可以重新载入这个文件,保证数据不会丢失;
(1)手动RDB文件命令: save(会阻塞服务器); bgsave(fork一个子进程创建RDB,完成后通知父进程)
(2)自动:save配置项:save seconds changes (距离上次创建RDB seconds秒,并且服务器发生不少于changes次修改),则执行bgsave
2.AOF持久化:RDB操作会将数据库所有内容进行保存,因此执行时间及资源耗费很多,执行的频率不能太高,在两次创建RDB文件的间隙,可以使用AOF持久化。AOF的过程是每当数据库命令执行时,将命令写入AOF文件
中。现代的操作系统会有写缓存,为了提高效率,写文件时首先会写到一个buffer里,buffer满了之后会调用fsync(详见http://blog.csdn.net/cywosp/article/details/8767327),而AOF只有真正写到硬盘才不会丢失数据,Redis提
供了配置控制写文件的时机:always(写一个命令调用一次fsync,效率会比较低), everysec(每秒调用一次,默认),no(由操作系统控制)
AOF重写:AOF文件中保存的是命令,因此占用空间比较大,Redis通过AOF重写减小占用空间,有几种方式触发AOF重写:
(1) 手动:bgrewrite命令
(2) auto-aof-rewrite-percentage&auto-aof-rewrite-min-size配置
四. Redis多机
1.单机的缺点: 内存容量不足; 单机qps有限
2.主从复制:从服务器处理部分或全部读请求,降低了主服务的负载。
创建方式:1. 向一台Redis发送 slaveof masterIP masterPort 2.配置文件中配置slaveof配置项
服务器下线:从服务器下线后会降低处理读请求的能力;主服务器下线后无法处理写请求,读请求仍可以被从服务器处理,但数据无法得到更新。解决方式:方式一:手动向一台从服务器发送slaveof no one,让其变成主服务器,逐个向其他
从服务器发送slaveof。方式二:使用Redis Sentinel监控主从服务器,进行自动故障转移。
3.twemproxy提高写性能:是一个客户端代理,它根据用户选择的散列函数(根据Redis键计算)和分布函数(一致性哈希,取模,随机),将数据分片存储在多个服务器上,当auto_eject_hosts为true,并且连续多次写数据
发生错误时,这台服务器被标记为下线,将原本由这台服务器负责的数据交给其他服务器处理。server_retry_timeout配置重新尝试写该服务器,如果还是无法写入,等待下次。
4.集群:Redis的集群特性包括了上述的复制,高可用和分片。集群的复制特性与分片与前文所说的基本相同,高可用与上述不同之处在于服务器的下线由集群中其他正常的主节点负责,无需Sentinel。
集群会给每个节点分配一定的槽位,对于不属于本节点负责的写请求Redis会返回一个重定向,之后客户端重新向正确节点发送写请求。