最近在 review 自己的知识,便于记录,落地了不少文字。字不如表,表不如图,图不如视频。抱着玩玩的心态,剪了一条与技术相关的小视频,发觉还是挺有意思的 。
压缩列表ziplist
是一个双向链表,设计主要是为了节省内存。
保存字符串,数值两种类型( It stores both strings and integer values),列表内部实现主要是对一块连续内存进行管理,列表支持列表头尾的插入或弹出结点操作。因为写操作涉及到内存重新分配,所以复杂度需要根据当前使用内存的使用情况而定,一般情况下,不建议存储大量数据。
sorted set
根据数据长度,就分别用 ziplist 和 skiplist
两种数据结构进行保存。
The ziplist is a specially encoded dually linked list that is designed to be very memory efficient. It stores both strings and integer values, where integers are encoded as actual integers instead of a series of characters. It allows push and pop operations on either side of the list in O(1) time. However, because every operation requires a reallocation of the memory used by the ziplist, the actual complexity is related to the amount of memory used by the ziplist.
redis 的链表实现不是很复杂,从 listNode
可以知道,list
是一个双向链表,支持从链表首尾两边开始遍历结点。同时提供了 listIter
迭代器,方便前后方向迭代遍历。其它应该就是链表增删改查的一些常规操作了。
nginx 内存池 (ngx_palloc.c) 主要对小内存的申请管理,避免频繁与底层交互,从而降低性能开销。
它是轻量级内存池,小内存主要分配策略主要是下次适配:从上次查询地方开始,遇到下一个合适的块停止。
redis 内存管理实现,有三种方案:
jemalloc
(谷歌)tcmalloc
(facebook)libc
(系统)其中 jemalloc
, tcmalloc
是第三方的实现,libc
的实现做了一些简单的封装。
为了节省内存空间,灵活处理不同长度范围的字符串,redis 定义了几种 sdshdr(X)
数据结构,对不同长度的字符串数据进行存储。
付费自习室,首先它是一个自习室,是一个满足不同行业人员学习充电的地方。其次它不是免费的,经营者为了打造高质量的学习环境,投入了不少资金。
redis 是 key-value 的 NoSQL 数据库,dict 是基础数据结构,dict 总体来说是一个哈希表
,哈希表 O(1) 的时间复杂度,能高效进行数据读取。
dict 还有动态扩容/缩容功能,能灵活高效地使用机器内存。
因为 redis 是单进程服务,所以当数据量很大时,扩容/缩容这些内存操作,涉及到新内存重新分配,数据拷贝,必然会影响服务质量。redis 作者采用了渐进方式,将一次性操作,分散到 dict 对应的各个增删改查操作里,每个操作触发有限的数据迁移。所以 dict 会有两个哈希表(dictht ht[2];
),相应的 rehashidx
迁移位置,方便数据迁移。
快捷登录阿里云效果
可以通过 gdb / vscode 调试 redis 源码,理解 redis 工作流程。
父进程 fork 子进程后,子进程通过 copy-on-write
模式获得父进程内存,也就是子进程共用了大部分父进程内存,只有当子进程在修改自己进程内存后,共享部分,才会把那些修改的拷贝出来,这样可以节省系统大量内存分配。
哨兵模式的 redis 集群,假如原来只有一个主服务,经过故障转移后,产生多个主服务,这样脑裂现象出现了。通过合理部署配置 sentinel/master,可以降低脑裂问题出现的概率。
对于“一天之计在于晨”,我比较倾向于早睡早起。
学习《算法导论》堆排序算法,做了一些笔记。测试源码在 (github)