深入C学习Redis核心设计原理及性能优化

这一块学的不是太透,简要做了一些笔记,分享一下,有机会再完善

Redis基本特性

  1. 非关系型键值数据库,O(1)时间复杂度存取值
  2. 数据存在内存
  3. 核心支持String,hash,list,set,sorted set 5大数据类型
  4. 支持磁盘持久化,LUA脚本、客户端缓存
  5. 支持哨兵及RedisCluster两种高可用集群模式

应用场景

  1. 数据缓存
  2. 计数器、分布式ID、会话缓存
  3. 数据队列、分布式锁、热数据存储等
  4. 排行榜、延迟队列(利用sorted_set实现)

字符串数据结构

  1. key的类型表面支持字符串数字,其实key都是string
  2. redis底层对string类型是sds数据结构(simple dynamic string)
  3. 底层为C语言实现,思考为啥不直接用C的字符串类型?
  4. sds结构:
sds:
    free: 3 // 减少内存扩容,以空间换时间
    len: 10 // 容量只增不减,以成倍机制扩容
    char buf[] = "qinchen" -> "qinchen123\0"
  1. sds支持根据字符串长度,用不同sdshdr类型存储,支持内存对齐
    • sdshdr5
    • sdshdr8
    • sdshdr16
    • sdshdr32
    • sdshdr64

数据结构

  1. 数组 + 链表
  2. 将key进行hash,再以数组长度取模,得到数组下标
  3. hash特点:任意相同输入,得到相同输出,不同输入,可能得到相同输出
  4. 也就是说将会出现hash碰撞,然后使用链表解决
(k1, v1),(k2, v2),(k3, v3)

hash(k1) % 4 = 0
hash(k2) % 4 = 1
hash(k3) % 4 = 1

arr[0] -> (k1, v1, next -> null)
arr[1] -> (k3, v3, next -> k2) (k2,v2, next -> null)
  1. c中的数据结构
redisDb:
    
    dictEntry
        *key // sds
        union {
            *val
            u64
            s64
            d
        } v;
        
        *next

    redisObject
        type // 数据类型 string/list/set...
        encoding  // 底层的编码形式 int/embstr...
        lru // 内存淘汰策略相关
        refcount // 引用计数,内存回收用
        *ptr; // 指向数据在内存中实际地址
    
    dictht
        **table
        size
        sizemask // size-1
        used;
  1. 对于set a 1000 redis底层做了优化,其值类型为int,直接利用引用指针属性存储,减少内存及CPU开销
  2. 字符串长度小于等于44,底层类型为embstr,超出后则为raw,目的提升性能
set 44byte aaaaaaaa... // 44个a
object encoding 44byte // 打印embstr
  1. bitmap类型
setbit login_12_12 USERID 1 // 值只能为0/1
getbit login_12_12 USERID // 返回1
bitcount login_12_12 // 统计
// 以上可用于统计用户日活场景,也可统计连续登陆统计(多个值做按位与)
bitop and login_1212-1113 login_12_12 login_12_13
// 还可按位或
bitop or xxxx xxxx xxxx

扩展知识:汉明重量;GeoHash经纬度编码

缓存穿透

  1. 多层缓存不命中
  2. 黑客可能攻击
  3. 可能对系统造成瘫痪
  4. 可通过缓存空对象、布隆过滤器等解决

缓存失效(击穿)

  1. 批量设置缓存,过期时间一致
  2. 在某一时间将批量失效
  3. 解决:将缓存超时时间+随机数设置

缓存雪崩

  1. Redis集群挂掉,导致流量全部导到数据库
  2. 数据库扛不住,应用不可用,最终整个系统瘫痪
  3. 解决方案:服务限流与降级,提前压测演练

热点缓存key重建优化

  1. 比如热点新闻事件,冷门商品突然抢购火爆
  2. 利用分布式锁挡

缓存与数据库双写不一致问题

  1. 多线程下,执行更新缓存先后顺序不能保证
  2. 解决方案:线程排队、延迟双删、分布式锁(推荐)
  3. 利用分布式锁的读写锁(读读不互斥,读写互斥)

开发规范与性能优化

  1. key设置:设前缀、防冲突,尽可能短,不含特殊符
  2. 防止bigkey(针对value),一般认为超10kb就是bigkey
  3. bigkey的危害:导致redis阻塞、网络拥塞、过期删除等问题
  4. 解决bigkey,尽可能拆小
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值