常见缓存数据库
- 缓解关系型数据库的并发访问的压力:热点数据
- 减少响应时间
- 提升吞吐量:单机内存数据库支持很大并发量
Redis数据类型及常用场景
-
string:简单的k,v值
- 应用:计数器,开关,分布式锁setnx
- 原理:最基础的数据结构
- 命令集:
1. SET/GET/APPEND/STRLEN: 2. INCR/DECR/INCRBY/DECRBY: 3. GETSET: 4. SETEX: 5. SETNX: 6. MSET/MGET/MSETNX:
-
list:列表的元素类型为string,按照插入顺序排序,在列表的头部或尾部添加元素
- 应用:队列,用户的关注,粉丝
- 原理:redis-3.2之前:ziplist(<512)或LinkedList双端链表(>512)3.2之后quicklist
ziplist:连续内存块实现list结构,每个entry头部保存前后节点的长度信息,从而实现双端链表的功能
- 命令集:
1. LPUSH/LPUSHX/LRANGE: 2. LPOP/LLEN: 3. LREM/LSET/LINDEX/LTRIM: 4. LINSERT: 5. RPUSH/RPUSHX/RPOP/RPOPLPUSH:
-
hash:彼此相关的信息的键值对
- 应用:存储用户信息,类似python的字段
- hashtable,数组+链表,碰撞时追加至链表
- hash特殊扩容机制(渐进式rehash):两个ht(新旧ht),每次发生增删改查时就会复制一个值到新ht,直到全部迁移完成,旧ht删除
- 命令集:
1. HSET/HGET/HDEL/HEXISTS/HLEN/HSETNX: 2. HINCRBY: 3. HGETALL/HKEYS/HVALS/HMGET/HMSET:
-
Set, 存储不重复的元素
- 应用:用户的关注者
- 原理:intset(<512)或hashtable(>512)
- 命令集:
1.SADD/SMEMBERS/SCARD/SISMEMBER: 2. SPOP/SREM/SRANDMEMBER/SMOVE:
-
sorted set,有序集合
- 应用:排行榜
- 原理: skiplist
- 对源链表进行多加几层,层层链接下一层,实现分层二分查找,查找到位置后进行插入
- 命令集
1.ZADD/ZCARD/ZCOUNT/ZREM/ZINCRBY/ZSCORE/ZRANGE/ZRANK: 2.ZRANGEBYSCORE/ZREMRANGEBYRANK/ZREMRANGEBYSCORE: 3.ZREVRANGE/ZREVRANGEBYSCORE/ZREVRANK:
Redis高级特性
持久化方式
- .RDB文件:快照方式
- 优点:定时手动备份时间点的数据文件,恢复速度快
- 缺点:某个时间点宕机了,有一段时间内的数据丢失
- .AOF(Append only file):每一个写命令追加到.aof文件中
- 优点:宕机不会缺失数据
- 缺点:恢复速度不如RDB,文件大
redis事务
- 多个请求打包,一次性按顺序执行
- MULTI,EXEC, WATCH[key]命令
原子性不支持回滚, 一致性有watch实现, 隔离性本身就是单线程,持久性不支持
go实现
使用 TxPipeline 或 TxPipelined 方法将 pipeline 命令使用 MULTI
和EXEC
包裹起来
Pipeline
将多个命令放入pipeline打包发送给sever,节省网络往返时间
分布式锁
为什么要分布式锁
- 用户下单
锁住 uid,防止重复下单。
- 库存扣减
锁住库存,防止超卖。
- 余额扣减
锁住账户,防止并发操作。
分布式系统中共享同一个资源时往往需要分布式锁来保证变更资源一致性。
特性
- 排他性
锁的基本特性,并且只能被第一个持有者持有。
- 防死锁
高并发场景下临界资源一旦发生死锁非常难以排查,通常可以通过设置超时时间到期自动释放锁来规避。
- 可重入
锁持有者支持可重入,防止锁持有者再次重入时锁被超时释放。
- 高性能高可用
锁是代码运行的关键前置节点,一旦不可用则业务直接就报故障了。高并发场景下,高性能高可用是基本要求。
实现
- setnx设置 key-value, expire设置超时时间
- 释放锁时,先判断有无锁,有锁及delete删除即可
常用的缓存使用模式
cache aside
先更新数据库–>删除缓存,下次读取无缓存时重建缓存
Read/Write Through
先更新缓存,缓存负责同步更新数据库
Write Behind Caching
先更新缓存,缓存负责定期异步更新数据库
缓存坑
缓存穿透
起因:大量缓存查不到,数据库中也没有
解决:将返回NULL的也存到缓存,插入数据的时候删除NULL缓存(或者设置短的超时时间,)
缓存击穿
起因:热点数据key过期,大量请求数据库
解决(两种):
分布式锁:一个线程获取锁查数据库更新缓存,其他线程等待,直到缓存中存在了,直接取
异步后台更新:异步对过期key自动刷新
缓存雪崩
起因:缓存服务不可用,或者大量key同时失效,大量请求数据库
解决:
针对缓存服务不可用—架构层的监控报警完善
针对大量key同时失效—key随机超时或多级缓存(不同级别的key不用的超时时间)
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/282189.html