Redis 的 EMPIRICAL_MAX_BIAS(常被误称为“EMBSTR”)是一个内部参数,用来决定何时创建一个特殊类型的字符串对象——即编码为 embstr 的对象。embstr 是 “embedded string” 的缩写,表示字符串数据和元数据紧密相连存储在同一块内存中,这样做的目的是为了减少内存开销和提高效率,特别是在处理较短的字符串时更为明显。
关于阈值 44 的解释
原本的阈值并不是 44,而是 39,但是由于一系列的历史变更和性能优化考量,最终确定了当前的 44。这个数值并非随机选取,它的设定主要考虑到以下几点:
- 内存效率:较小的字符串通常会被大量使用,因此减少它们的内存占用是非常有益的。
- 性能优化:embstr 结构体本身包含了一些必要的元数据字段,例如 LRU 时间戳和引用计数等,因此字符串的有效载荷必须大于等于 32 字节,加上这些元数据字段,使得整个对象的大小不会因过度封装而变得低效。
最初,由于 Redis 的对象头部固定为 16 字节(包括 8 字节的元数据和至少 8 字节的空闲空间),加上至少 32 字节的有效载荷,总共需要 48 字节的空间。然而,由于内存对齐的要求,实际分配的最小单元通常是 64 字节,这就留下了 16 字节的空余空间,可以用于存储更长一点的字符串而无需额外的内存分配。
阈值调整的历史背景
随着 Redis 发展,其内部实现细节不断优化。例如,从 Redis 2.6 版本开始,对象头的结构进行了改进,引入了更紧凑的表示形式(compact representation)。这使得对象头的大小从固定的 16 字节降低到了动态变化,取决于是否启用了 LRU 或其他特性。这一改变使得 embstr 对象可以容纳稍微长一点的字符串而不牺牲性能。
在 Redis 3.x 的某个版本中,阈值被调整到了 44。这一变动主要是因为在对象头结构调整后,可以利用的部分空余空间增加了,从而允许更大的字符串以 embstr 形式存在,提高了内存利用率和性能。
总结
简而言之,Redis 中 embstr 对象的阈值设置成 44,是为了在内存效率和性能之间取得平衡,确保小字符串的存储既高效又快速。这个数值经历了从早期的 39 到现在的 44 的演变,反映了 Redis 内部优化过程中的持续改进和技术演进。
需要注意的是,虽然 embstr 提升了小型字符串的效率,但它也有自己的局限性。例如,一旦字符串超过了这个阈值,就会转为常规的字符串编码,这时如果再有更新操作,可能触发重新分配和拷贝,带来额外的性能开销。因此,了解 embstr 的工作机制及其背后的逻辑,对于优化 Redis 应用程序的性能非常重要。