34 | 第23~33讲课后思考题答案及常见问题答疑

145 阅读5分钟

问题:Redis 的只读缓存和使用直写策略的读写缓存,都会把数据同步写到后端数据库中,你觉得它们有什么区别吗?

  • 当数据被修改时

    • 只读缓存:修改数据库,并删除缓存
    • 直写策略的读写缓存:同时修改缓存和数据库

问题:Redis 缓存在处理脏数据时,不仅会修改数据,还会把它写回数据库。我们在前面学过 Redis 的只读缓存模式和两种读写缓存模式(带同步直写的读写模式,带异步写回的读写模式)),请你思考下,Redis 缓存对应哪一种或哪几种模式?

  • 如果我们在使用 Redis 缓存时,需要把脏数据写回数据库,这就意味着,Redis 中缓存的数据可以直接被修改,这就对应了读写缓存模式\

  • 异步写回策略的读写缓存模式\

\

问题:在只读缓存中对数据进行删改时,需要在缓存中删除相应的缓存值。如果在这个过程中,我们不是删除缓存值,而是直接更新缓存的值,你觉得,和删除缓存值相比,直接更新缓存值有什么好处和不足吗?

  • 优点:更新缓存值,下次可以直接读取,不需要到数据库后回存

  • 缺点:引入更多方法保证缓存和数据库中的数据是一致的

    • 重试
    • 延时双删

问题:在讲到缓存雪崩时,我提到,可以采用服务熔断、服务降级、请求限流三种方法来应对。请你思考下,这三个方法可以用来应对缓存穿透问题吗?

  • 缓存击穿:查询了缓存和数据库都没有的数据

    • 服务熔断、服务降级和请求限流的方法,本质上是为了解决 Redis 实例没有起到缓存层作用的问题\

    • 所以缓存雪崩和缓存击穿属于这类问题

  • 解决缓存击穿的办法

    • 事前拦截:布隆过滤器\

    • 事后补救:服务熔断、服务降级、请求限流(有损方案)

问题:使用了 LFU 策略后,缓存还会被污染吗?

  • 是有可能发生污染
  • LFU 策略使用的计数器可能会在短时间内达到一个很大值,而计数器的衰减配置项设置得较大,导致计数器值衰减很慢

\

问题:这节课,我向你介绍的是使用 SSD 作为内存容量的扩展,增加 Redis 实例的数据保存量,我想请你来聊一聊,我们可以使用机械硬盘来作为实例容量扩展吗?有什么好处或不足吗?

  • 从容量维度来看:机械硬盘的性价比更高,机械硬盘每 GB 的成本大约在 0.1 元左右,而 SSD 每 GB 的成本大约是 0.4~0.6 元左右\

  • 从性能角度来看:机械硬盘(例如 SAS 盘)的延迟大约在 35ms,而企业级 SSD 的读延迟大约是 6080us,写延迟在 20us。缓存的负载特征一般是小粒度数据、高并发请求,要求访问延迟低。所以,如果使用机械硬盘作为 Pika 底层存储设备的话,缓存的访问性能就会降低。\

  • SSD>机械硬盘

\

问题:Redis 在执行 Lua 脚本时,是可以保证原子性的,那么,在课程里举的 Lua 脚本例子(lua.script)中,你觉得是否需要把读取客户端 ip 的访问次数,也就是 GET(ip),以及判断访问次数是否超过 20 的判断逻辑,也加到 Lua 脚本中吗?

  • 不需要,因为并发读不存在原子性,没有进入临界区

\

问题:在课程里,我提到,我们可以使用 SET 命令带上 NX 和 EX/PX 选项进行加锁操作,那么,我们是否可以用下面的方式来实现加锁操作呢?

| ``` // 加锁SETNX

lock_key unique_value

EXPIRE lock_key 10S

// 业务逻辑

DO THINGS

| ------------------------------------------------------------------------------------------------------------ |

-   两个操作没有保证原子性,第一个操作成功,第二操作失败,则会造成死锁

\


问题:在执行事务时,如果 Redis 实例发生故障,而 Redis 使用的是 RDB 机制,那么,事务的原子性还能得到保证吗?

-   事务执行过程中,对数据的修改不会实时记录到RDB中,事务执行完成后执行RDB操作

-   假设事务在执行到一半时,实例发生了故障\


    -   数据丢失,保证原子性

-   假设事务执行完成后,RDB 快照已经生成了\


    -   数据保存,可以恢复,保证原子性

-   假设事务执行已经完成,但是 RDB 快照还没有生成\


    -   数据丢失,保证原子性

\


问题:在主从集群中,我们把 slave-read-only 设置为 no,让从库也能直接删除数据,以此来避免读到过期数据。你觉得,这是一个好方法吗?

-   不是,从库可以删除会导致数据不一致

-   从库删除导致的数据不一致

    -   从库由于网络延时未收到续费通知,误删数据

    -   主从库的时钟不同步,导致主从库删除时间不一致\


        -   设置slave-read-only 设置为no时
        -   Redis 4.0 前的版本不会删除过期数据\

        -   Redis 4.0 及以上版本会在数据过期后删除

\


问题:假设我们将 min-slaves-to-write 设置为 1,min-slaves-max-lag 设置为 15s,哨兵的 down-after-milliseconds 设置为 10s,哨兵主从切换需要 5s,而主库因为某些原因卡住了 12s。此时,还会发生脑裂吗?主从切换完成后,数据会丢失吗?

-   会丢失主库降级为从库的数据

\