Redis的List用过吗?底层怎么实现的?知道但是没用过,不知道怎么实现
Redis基本数据结构
String(int,sds)
字符串,整数,浮点数List(linkedList,zipList)
<zlbytes><zltail><zllen><entry>...<entry>...<zlend>
zlbytes表示本ziplist的总长度
zltail指向最末的元素
zllen表示元素个数
zlend恒为0xFF作为ziplist的定界符
每个entry内部结构包含两部分
相邻的前一个entry的长度
自描述的本entry长度
方便双向遍历
- Map
hashtable ziplist
map对应的ziplist的entry的个数总是2的整数倍
第奇数个entry存放key
key对应的entry的下一个相邻entry存放该key对应的value - set
intset - sorted-set
ziplist或者
hashtable + skiplist - zset
ziplist:满足以下两个条件的时候
元素数量少于128的时候每
个元素的长度小于64字节skiplist
不满足上述两个条件就会使用跳表,具体来说是组合了map和skiplist
map用来存储member到score的映射,这样就可以在O(1)时间内找到member对应的分数
skiplist按从小到大的顺序存储分数
skiplist每个元素的值都是[score,value]对
因为有了skiplist,才能在O(logN)的时间内插入一个元素,并且实现快速的按分数范围查找元素
*2
$4
auth
$3
foo
- 事务
multi
exec/discard
redis> MULTI
OK
redis> SET book-name "Mastering C++ in 21 days"
QUEUED
redis> GET book-name
QUEUED
redis> SADD tag "C++" "Programming" "Mastering Series"
QUEUED
redis> SMEMBERS tag
QUEUED
redis> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
2) "C++"
3) "Programming"
watch/unwatch
127.0.0.1:6379> watch msg
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set msg "hello wolrd"
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get msg
"12345"
127.0.0.1:6379>
- save,bgsave
save都是以普通命令的方式执行---单线程串行化的执行一个命令
bgsave命令执行始于fork出一个子线程
产生一个快照,后续执行的新的客户端命令对数据状态产生的变更将不会反应在本次快照文件中
子进程fork时,涉及父进程内存的复制,其存在期间会增加服务器内存的开销 - aof持久化
将当前命令的内容append到aof_buf变量中,然后write到aof文件中,但是write操作只是将数据写到缓存,只有显式调用fsync方法,才能强制让操作系统落地数据到磁盘 - aof重写
重写的快照,仍然采用cmd形式来承载,只是将快照的所有key value值用插入命令来表示