redis命令参考 http://redisdoc.com/
pipelining
#网络往返次数线性增长,4次RTT (Round Trip Time),改进如下
服务器用队列存储命令以及响应,1次RTT,节约网络传输,但是耗内存
Expires
- 举例 redis>SET mykey "Hello" OK redis> EXPIRE mykey 10 (integer) 1 redis> TTL mykey (integer) 10 redis> SET mykey "Hello World" OK redis> TTL mykey (integer) -1
- 要点
除非显式del,默认永不过期,expire修改过期时间,persist永不过期 - 实现方式
被动发现:访问时检测发现过期,原文档A key is actively expired simply when some client tries to access it, and the key is found to be timed out.
主动扫描: 概率性算法,定期扫描一定数量(20)的key,把其中过期的删除,如果超过25%的过期,则再次重复扫描一定数量(20)的key,直到过期率低于25%
transactions
- 举例
> MULTI
> INCR foo
> INCR bar
> EXEC
- 概述
事务保证multi到exec之间的多条指令按顺序执行,且不会被其他指令穿插执行.multi仅仅把指令依次检查语法并放入队列,exec才是按顺序执行.
如果指令入队列失败(语法错误,内存不足),server不是返回QUEUED,而是error,此时大多数client会discard终止事务
如果exec阶段某条指令出错,记录错误信息,继续执行余下指令。exec不终止事务,不回滚事务.不支持回滚理由:1.语法错误,入队列时即可检测,programming errors应该在测试环境调试修复2.保证高效率 - 乐观锁check-and-set (CAS)
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
watch监测mykey,如被其他人修改(过期不算被修改),则不执行set指令
exec指令结束后,所有被watch的key,都被unwatch
Mass Insertion
- 用法
cat data.txt | redis-cli --pipe
python data.py | redis-cli --pipe - 原理
- redis-cli --pipe以最快速度向server发数据,同时当有数据返回时(事件驱动),尝试解析响应(解析会计数,用于统计多少条指令成功)
- 当数据发送完毕,发送指令“echo an_random_20_bytes_str”,然后检查响应,是否有相同的20字节的随机字符串返回(验证最后一条echo指令是否成功执行)
Data type Summary
- Strings
incr, decr, incrby计数增加,append追加字符串,getrange,setrange切片读取,getbit,setbit对字符串某个字节读写 - Lists
lpush,rpush分别头尾插入;lpush+lrange取最新,lpush+trim实现latest N,前置b,如blpop实现同步操作 - Sets
sadd添加,spop移除,此外还有如求交集并集等集合运算 - Hashs<双列数据结构key,value>
hset, hmset设置,批量设置;hgetall获取
Persistence
- RDB
所有数据dump成一个文件(类似快照),恢复速度比AOF快
全量备份时间粒度粗<总不能1分钟1次吧>,会丢失最新一定粒度时间的数据,数据量超大时,从磁盘读取RDB文件耗时 - AOF<同mongo journal>
通过记录操作日志,恢复时重演一遍操作动作实现数据备份与恢复。并且自带rewrite优化,比如对a +1; a+1; a+1;三条日志,合并为一条a + 3;
AOF文件远大于RDB文件,aof记录过程<每一步动作>,rdb记录结果<快照时最终状态>,恢复时AOF略慢,需要重演一遍动作
Replication(master-slave)
- 要点
slave异步更新,non-blocking 主从在同步时均可同时处理请求,主节点要么开启持久化,要么关闭自动重启:主节点在不持久化的情境下意外重启,数据集为空,导致从节点盲目同步丢失数据 - 原理
1.slave发送SYNC指令,master启动后台进程保存数据到磁盘,并且缓存从此时间点开始的数据操作请求(指令)。
2.保存完毕后发送给slave,slave接收写磁盘并加载数据到内存。
3.master继续发送缓存的数据操作请求(指令)到slave,slave接收并重演一遍这些请求(指令)从而达到与master同步。 - 部署
slaveofmaster_ip master_port
断开主从:slave of no one
其他:slave-read-only(默认False,可写)
主从加强(至少N个节点延迟小于M秒):min-slaves-to-write, min-slaves-max-lag(有点类似mongodb write concern)master至少要传递写操作到几个副本才算有效。
cluster
Cluster bus:心跳机制,节点之间的健康监测
分片算法:不是一致性hash.每个key是hash slot的一部分,对于任意key,通过CRC16算法对16384求模,即可确定该key落在哪一个hash slot.假设3个节点,A负责hash slot 0--5500,B负责5501--11000,C负责11001--16834,所以节点数目变动会有数据迁移达到新的平衡。
对于cluster每个shard node,可以再用主从,保证某个分片故障时,该分片的从节点顶上。
可能数据丢失:master接受write请求,并执行,但是在同步给所有slave之前宕机,然后没有被同步的slave选举成为新的master,此write永久丢失。
- 配置项
cluster-enabled(yes/no):决定该redis实例是stand alone还是当作shard node
cluster-config-file(filename):shard节点把cluster配置信息存在哪个文件
cluster-node-timeout(milliseconds):健康检测超时值,master超过该值连不上shard,就认为该shard挂了;shard连不上master,将停止接受请求
cluster-slave-validity-factor(factor):最大失败次数,slave连接master失败多少次后触发failover。
cluster-migration-barrier:与master保持链接的最小shard节点数
cluster-require-full-coverage:是否必须工作在数据集完整的条件下。如果某个shard挂了,设置yes,由于工作在sub-set数据集,拒绝写入。否则,即使只有部分数据,继续工作。 - 部署 port 700x
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes 700x表示最后一个x是变化的,每个shard node用一个不同的端口,比如6个节点,分别7000 ---7005
用6份这个配置文件,分别起6个redis,注意cluster-enabled yes,工作在cluster模式 ../redis-server ./redis700x.conf ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \ 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 redis-trib utility is in the src directory of the Redis source code distribution.上面命令 create a cluster with 3 masters and 3 slaves - Creating a Redis Cluster using the create-cluster script
utils/create-cluster目录下create-cluster脚本
create-cluster start
create-cluster create
create-cluster stop
节点的增加删除,resharding 点http://redis.io/topics/cluster-tutorial
更深入学习cluster http://redis.io/topics/cluster-spec