Why Redis?
- Redis是一种运行速度很快,并发很强,跑在内存上的NoSql数据库,反对键到五种数据类型的映射。依据Redis官网提供的benchmark测试数据,redis读的速度是110000次/s,写的速度是81000次/s,并且试验证实,数据没在缓存的时候,雷同条件下用Jmeter进行压测,redis的申请处理速度比MySQL高了7倍。另外,在工夫局部性原理很强的场景下,Redis能够从缓存迅速响应,而不是去数据库查sql,尤其是曾经放入缓存的数据,这体现出了Redis的高性能;
- Redis是单线程的,防止了多线程上下文的切换和锁竞争的工夫开销。(在Redis6.0之后在网络读写时已替换成多线程,但执行命令依然是单线程)
- Redis指令是原子性的,高并发时不会产生数据异样,Redis 应用 I/O 多路复用技术,能够解决高并发的连贯(非阻塞I/O),这意味着可能让一个计算单元来解决来自多个客户端的流申请实现高并发。
想要深刻理解Redis,这本《Redis 设计与实现》就无奈绕开了。
第一局部 数据结构与对象
简略动静字符串 SDS
SDS对标的是C语言的String,通过在底层实现数组buf的根底上减少len和free字段,实现了
- 常数复杂度获取字符串长度
- 杜绝缓冲区溢出
- 缩小批改字符串时带来的内存重调配次数
实现的原理也巨简略,,,C的String不记录len,每次都只能遍历String工夫复杂度O(n),SDS空间换工夫用一个len记录一下,工夫复杂度间接降到O(1),这就能解释下面的1和2,至于3就是free这个字段的作用了,redis应用了空间预调配和惰性空间开释策略,说白了就是SDS批改之后如果变长了,理论调配的空间不仅仅是len,会依据SDS长度定,如果新的SDS小于1M,新的SDS大小就在原根底上double+1,为啥double,因为这里会多调配一倍给free,这就是空间预调配;为啥+1byte,因为最初一个字节保留空字符,为啥保留空字符,为了更好的兼容C语言对字符串的操作,对的,没有看错,Redis底层就是用的规范C语言实现的。如果新的SDS大于1M,free就等于1M,新的SDS就等于旧的SDS+1M+1byte。
C语言中对String进行的各种操作,SDS天然也有对应的API,详见http://redisbook.com/preview/...
链表
因为C语言没有将链作为内置数据结构,Redis用ListNode和指针实现了双向链表
typedef struct listNode{ struct listNode *prev; struct listNode *next; void *value;}listNode;
未完待续。
参考: 黄健宏. Redis 设计与实现[M]. Ji xie gong ye chu ban she, 2014.
https://zhuanlan.zhihu.com/p/...
https://youle.zhipin.com/ques...