阿里P6之七NoSQL数据库Redis

个人专题目录


7. NoSQL数据库Redis

7.1 在你的项目中,哪些数据是数据库和Redis缓存双写一份的?如何保证双写一致性?

高并发场景下的redis缓存和数据库双写不一致问题分析与解决方案设计

7.2 系统上线,Redis缓存系统是如何部署的

redis cluster,10台机器,5台机器部署了redis主实例,另外5台机器部署了redis的从实例,每个主实例挂了一个从实例,5个节点对外提供读写服务,每个节点的读写高峰qps可能可以达到每秒5万,5台机器最多是25万读写请求/s。

机器是什么配置?32G内存+8核CPU+1T磁盘,但是分配给redis进程的是10g内存,一般线上生产环境,redis的内存尽量不要超过10g,超过10g可能会有问题。

5台机器对外提供读写,一共有50g内存。

因为每个主实例都挂了一个从实例,所以是高可用的,任何一个主实例宕机,都会自动故障迁移,redis从实例会自动变成主实例继续提供读写服务

你往内存里写的是什么数据?每条数据的大小是多少?商品数据,每条数据是10kb。100条数据是1mb,10万条数据是1g。常驻内存的是200万条商品数据,占用内存是20g,仅仅不到总内存的50%。

目前高峰期每秒就是3500左右的请求量

7.3 系统上线,Redis缓存给了多大的总内存?命中率有多高?抗住了多少QPS?数据流回源会有多少QPS?

http://fivezh.github.io/2019/02/11/cache-things/

命中率计算:

info命令:比如

keyspace_hits:14414110
keyspace_misses:3228654
used_memory:433264648
expired_keys:1333536
evicted_keys:1547380
  • 查询命中数: 查询的命中个数,对应 keyspace_hits 字段。
  • 查询未命中数: 查询的未命中个数,对应 keyspace_misses 字段。
  • 查询命中率: 查询命中率,对应 keyspace_hits / ( keyspace_hits + keyspace_misses )。
  • 总Key个数: 缓存中总的 key 个数,所有 db 的 key 个数总和。
  • 已过期Key个数: 缓存中已过期 Key 个数,对应 expired_keys 字段。
    当缓存内存不足时,会根据用户配置的 maxmemory-policy 来选择性地删除一些 key 来保护内存不溢出
  • 通过计算hits和miss,我们可以得到缓存的命中率:14414110 / (14414110 + 3228654) = 81% ,一个缓存失效机制,和过期时间设计良好的系统,命中率可以做到95%以上

7.4 热Key大Value问题,某个key出现了热点缓存导致缓存集群中的某个机器负载过高?如何发现并解决

解决热点key问题,可以有以下几种方案:

  1. 互斥锁:查询数据库的过程,只让一个线程独占,这个线程构建缓存的过程,其他线程都要等待,直到第一个线程构建完成可以从中读取数据。
  2. 提前使用互斥锁:提前使用互斥锁,和互斥锁差不多,都是让一个线程独占构建缓存,不一样的是,在构建缓存的时候。在value内部设置一个超时值timeout1,这个过期时间比实际的缓存过期时间短。当从缓存中读到timeout1已经过期的时候,就认为数据也快过期了,直接执行查询数据库,进行构建缓存的过程。这样在所有快过期的数据前,就重新构建了缓存。
  3. 永远不过期
    1. 从redis上看,确实没有设置过期时间,这就保证了,不会出现热点key过期问题,也就是“物理”不过期。
    2. 从功能上看,如果不过期,那不就成静态的了吗?所以我们把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建,也就是“逻辑”过期

Redis使用过程中经常会有各种大key的情况, 比如:

  • 单个简单的key存储的value很大
  • hash, set,zset,list 中存储过多的元素(以万为单位)
    由于redis是单线程运行的,如果一次操作的value很大会对整个redis的响应时间造成负面影响,所以,业务上能拆则拆,下面举几个典型的分拆方案。
  1. 单个简单的key存储的value很大
    1. 改对象需要每次都整存整取
      1. 可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响;
    2. 该对象每次只需要存取部分数据
      1. 可以像第一种做法一样,分拆成几个key-value, 也可以将这个存储在一个hash中,每个field代表一个具体的属性,使用hget,hmget来获取部分的value,使用hset,hmset来更新部分属性
    3. hash、set、zset、list 中存储过多的元素
      1. 类似于场景一种的第一个做法,可以将这些元素分拆。以hash为例,原先的正常存取流程是 hget(hashKey, field) ; hset(hashKey, field, value)
        现在,固定一个桶的数量,比如 10000, 每次存取的时候,先在本地计算field的hash值,模除 10000, 确定了该field落在哪个key上。set, zset, list 也可以类似上述做法.

7.5 超大Value打满网卡的问题如何规避

  • 业务设计上避免
  • 对于大文本【超过500字节】写入到Redis时,一定要压缩后存储!大文本数据存入Redis,除了带来极大的内存占用外,在访问量高时,很容易就会将网卡流量占满,进而造成整个服务器上的所有服务不可用,并引发雪崩效应,造成各个系统瘫痪!

7.6 你过往的工作经历中,是否出现过缓存集群事故?说说怎么保证高可用的?

redis cluster vs. replication + sentinal

如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机足够了

replication,一个mater,多个slave,要几个slave跟你的要求的读吞吐量有关系,然后自己搭建一个sentinal集群,去保证redis主从架构的高可用性,就可以了

redis cluster,主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster

7.7 平时如何监控缓存集群的QPS和容量

Redis监控

7.8 缓存集群如何扩容?

Redis集群水平扩展

7.9 说下redis的集群原理和选举机制

Redis 集群模式的工作原理

7.10 Key寻址算法都有哪些?

分布式寻址算法

  • hash 算法(大量缓存重建)
    • 来了一个 key,首先计算 hash 值,然后对节点数取模。然后打在不同的 master 节点上。一旦某一个 master 节点宕机,所有请求过来,都会基于最新的剩余 master 节点数去取模,尝试去取数据。这会导致大部分的请求过来,全部无法拿到有效的缓存,导致大量的流量涌入数据库。
  • 一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡)
    • 一致性 hash 算法将整个 hash 值空间组织成一个虚拟的圆环,整个空间按顺时针方向组织,下一步将各个 master 节点(使用服务器的 ip 或主机名)进行 hash。这样就能确定每个节点在其哈希环上的位置。
    • 来了一个 key,首先计算 hash 值,并确定此数据在环上的位置,从此位置沿环顺时针“行走”,遇到的第一个 master 节点就是 key 所在位置。
    • 在一致性哈希算法中,如果一个节点挂了,受影响的数据仅仅是此节点到环空间前一个节点(沿着逆时针方向行走遇到的第一个节点)之间的数据,其它不受影响。增加一个节点也同理。
    • 一致性哈希算法在节点太少时,容易因为节点分布不均匀而造成缓存热点的问题。为了解决这种热点问题,一致性 hash 算法引入了虚拟节点机制,即对每一个节点计算多个 hash,每个计算结果位置都放置一个虚拟节点。这样就实现了数据的均匀分布,负载均衡。
  • redis cluster 的 hash slot 算法
    • redis cluster 有固定的 16384 个 hash slot,对每个 key 计算 CRC16 值,然后对 16384 取模,可以获取 key 对应的 hash slot。
    • edis cluster 中每个 master 都会持有部分 slot,比如有 3 个 master,那么可能每个 master 持有 5000 多个 hash slot。hash slot 让 node 的增加和移除很简单,增加一个 master,就将其他 master 的 hash slot 移动部分过去,减少一个 master,就将它的 hash slot 移动到其他 master 上去。移动 hash slot 的成本是非常低的。客户端的 api,可以对指定的数据,让他们走同一个 hash slot,通过 hash tag 来实现。
    • 任何一台机器宕机,另外两个节点,不影响的。因为 key 找的是 hash slot,不是机器。

7.11 Redis线程模型画个图说说

Redis线程模型

7.12 Redis内存模型画个图说说

Redis内存模型

7.13 Redis中的Lua有没有使用过? 可以用来做什么? 为什么可以这么用?

Lua:
https://www.cnblogs.com/huangxincheng/p/6230129.html

  1. 减少网络开销:可以将多个请求通过脚本的形式一次发送,减少网络时延和请求次数。
  2. 原子性的操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。
  3. 代码复用:客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本来完成相同的逻辑。

7.14 缓存穿透和缓存雪崩?

缓存穿透含义:一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就去DB查找。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对DB造成很大的压力。这就叫做缓存穿透。

缓存穿透解决方案:

  • 对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存;
  • 对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的set中,查询时通过该set过滤(用的较少);

缓存雪崩含义:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给DB带来很大压力;
缓存雪崩解决方案:

  • 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待;
  • 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀;
  • 做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容