2022-01-30 08:18:47
解决方案概述针对Redis存储百亿级Key的挑战,需从数据结构设计、内存优化、淘汰策略三方面综合优化。以下是具体方案:
1. 数据结构设计优化1.1 减少Key数量BucketId分桶技术:
对原始Key(如supperid、media_cookie)计算MD5哈希,截取部分位生成固定长度的BucketId(如30位二进制,对应约10亿桶)。
将多个Key-Value存储在同一个Redis Hash结构中(BucketId作为Hash的Key,原始Key作为Hash的Field)。
效果:若每桶平均挂载10个Key,Key总数可减少90%以上。
Key截断优化:
对Hash内的Field(如media_cookie)截取后6位作为短Key,利用随机性降低冲突概率(冲突期望值<0.05)。
将age、gender、geo编码为紧凑格式(如3字节),避免冗余字段。
直接存储supperid或设备ID的映射关系,减少嵌套结构。
所有BucketId和短Key长度固定,确保内存对齐。
使用jemalloc或tcmalloc替代默认libc,尤其在Value较小时显著减少碎片。
通过重启Slave并触发Failover,间接整理Master内存(需谨慎操作)。
Redis默认使用ziplist编码Hash结构,但大量Key时需显式配置hash-max-ziplist-entries和hash-max-ziplist-value以优化内存。
所有Key默认设置35天TTL,通过HBase预聚合去重,避免存储无效ID。
命中Key时延长TTL(如续期至35天),未命中则自然淘汰。
适用场景:对idfa、imei等稳定ID效果显著。
当天新增Mapping和标签必须全量加载至Redis,确保公网延迟<100ms。
35天后未访问的数据自动淘汰,如需历史数据可通过HBase查询(牺牲实时性)。
按BucketId范围分片,避免单节点内存压力(如10亿Key/节点)。
主从复制仅同步热数据,减少带宽和存储开销。
适用场景:高并发、低延迟的实时DMP系统,需处理千亿级动态ID映射和标签查询。