Redis Persistence
Based on Redis 7.0.11. Redis 提供了四种持久化的方式: No persistence:不做持久化处理,用得较少。 RDB:对缓存做全量 point-in-time 快照,生成的 *.rdb 文件非常紧凑,加载性能高,非 human readable。 AOF:对每个 write operation 进行记录,通过 replay 重新生成当前缓存状态,记录按照 RESP 格式存储,human readable。 RDB + AOF:结合 RDB 与 AOF。 RDB命令&配置SAVE 在当前进程生成快照,会阻塞服务;BGSAVE 在子进程中生成快照,不会阻塞服务。 除手动执行 SAVE 和 BGSAVE,Redis 允许配置 BGSAVE 自动执行的条件: 12save M N # At lease N changes in the last M secondssave ... 满足多个条件中任意一条即可自动执行 BGSAVE。 BGSAVE 执行过程 Fork 子进程 子进程将数据写入临时 RDB 文件 子进程将临时 RDB 文件重命名替换 ...
Redis 键的生存时间
设置过期时间 命令 作用 EXPIRE seconds 设置剩余生存时间 PEXPIRE milliseconds 同上,单位毫秒 EXPIREAT seconds-timestamp 设置过期时间戳 PEXPIREAT milliseconds-timestamp 同上,单位毫秒 SETEX / SET EX 专用于 String PERSIST 去除过期时间 设置过期时间命令最终都会调用 PEXPIREAT,当键发生更新时,过期时间失效。 剩余生存时间TTL key or PTTL key。 过期键删除策略三种策略: 定时删除:对键设置过期时间的同时,设置一个 timer,timer 到期后立即删除键。 惰性删除:在访问时做过期检查,过期则先删除,再执行原来的操作。 定期删除:周期性地删除一批过期键。 定期删除,内存友好,CPU 不友好。过期键较多时会大量占用 CPU,同时需要注册时间事件。惰性删除对内存不友好,如果键过期后一直没被访问,则此键将一直驻留在内存中。定期删除是前两种地折衷,Redis 中是遍历数据库,然后从 expire ...
Redis Object
Based on Redis 7.0.11. Redis 对外支持的数据类型(String、List、Hash、Set、ZSet)并不是直接使用其定义的数据结构,而是基于另外的一套对象系统。对象系统除了可以根据不同场景选择不同底层数据结构外,还实现了基于引用计数的对象共享和垃圾回收以及缓存淘汰机制。 Redis Object 定义123456789typedef struct redisObject { unsigned type:4; unsigned encoding:4; unsigned lru:24; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency * and most significant 16 bits access time). */ int refcount; void *ptr; ...
Redis Ziplist
Based on Redis 7.0.11. Ziplist 定义Ziplist 没有像其它数据结构一样提供明确的 struct 定义,因为部分成员的大小不是固定的,以达到节省内存的目的。提供的 struct 也只是为了方便读取信息。所以就贴一下注释内容吧: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142/* * ZIPLIST OVERALL LAYOUT * ==================== ...
Redis Intset
Based on Redis 7.0.11. Intset 定义12345typedef struct intset { uint32_t encoding; uint32_t length; int8_t contents[];} intset; encoding:整数的编码方式,实际上表示整数的取值范围(占用字节)。可选值有 INSET_ENC_INT16、INSET_ENC_INT32 和 INSET_ENC_INT64。 length:整数个数,通过 length 和 encoding 可以计算出 contents 大小。 contents:字节数组,每次 Add 或 Remove 都会引起 contents 长度变化(realloc)。 升级升级指 enocding 由较少字节占用扩展到更多字节占用。升级由超过当前 encoding 所能表示的上下限的新元素引起,这个时候新元素要么在 contents 头部,要么在尾部插入。 降级不支持降级。 Key takeawaysintset.h 《Redis 设计与实现》
Redis Skiplist
Based on Redis 7.0.11. Skiplist 定义123456789101112131415typedef struct zskiplistNode { sds ele; double score; struct zskiplistNode *backward; struct zskiplistLevel { struct zskiplistNode *forward; unsigned long span; } level[];} zskiplistNode;typedef struct zskiplist { struct zskiplistNode *header, *tail; unsigned long length; int level;} zskiplist; zskiplistNode.score:节点的权重,它决定了节点在列表中的位置(从小到大);分值相同的节点则按照 ele 的字典顺序排序。 zskipli ...
Redis Hash Tables
Based on Redis 7.0.11. Hash table 定义123456789101112131415161718192021222324252627282930313233343536373839typedef struct dictEntry { void *key; union { void *val; uint64_t u64; int64_t s64; double d; } v; struct dictEntry *next; /* Next entry in the same hash bucket. */ void *metadata[]; /* An arbitrary number of bytes (starting at a * pointer-aligned address) of size as returned ...
Redis Doubly Linked List
Based on Redis 7.0.11. Doubly linked list 定义1234567891011121314typedef struct listNode { struct listNode *prev; struct listNode *next; void *value;} listNode;typedef struct list { listNode *head; listNode *tail; void *(*dup)(void *ptr); void (*free)(void *ptr); int (*match)(void *ptr, void *key); unsigned long len;} list; value: 链表节点使用 void * 保存值,结合 dup、free 和 match 实现了对多态支持。 dup: 拷贝 value 用,如果没有设置则默认浅拷贝。 free: 回收 value 用,如果没有设置就不对 value 进行额外回收处 ...
Redis SDS
Based on Redis 7.0.11. SDS 定义12345678910111213141516171819202122232425262728293031323334353637383940typedef char *sds;#define SDS_TYPE_5 0 // 0b0000#define SDS_TYPE_8 1 // 0b0001#define SDS_TYPE_16 2 // 0b0010#define SDS_TYPE_32 3 // 0b0011#define SDS_TYPE_64 4 // 0b0100#define SDS_TYPE_MASK 7 // 0b0111#define SDS_TYPE_BITS 3 /* Note: sdshdr5 is never used, we just access the flags byte directly. * However is here to document the layout of type 5 SDS strings. */struct __attribute__ ...
《Domain Driven Design》
去年连着刷完了《领域驱动设计》、《实现领域驱动设计》和《领域驱动设计精粹》,碰到一些案例讲解,走马观花就过了。春节前后两三个月(摸鱼太多)二刷《领域驱动设计》,虽然最后两章《大型结构》和《领域驱动设计的综合运用》还是没能体会透彻,但是相比第一遍时的那种朦胧感,对领域驱动设计的理解要清晰得多了。 概览 A brief introduction to DDD from ChatGPT Domain-Driven Design (DDD) is a philosophy and software development methodology that aims to help teams build complex software solutions that closely match the domain of the problem they’re trying to solve. Instead of focusing on architecture, DDD emphasizes domain analysis, modeling, and design. In DDD, t ...