7、常考其他

厨子大约 6 分钟数据库原创面试题Redis程序厨

7.常考其他

Redision、Jedis、lettuce等等,官方推荐是Redission

7.1 Redission 和 Redis有什么关系

Redission是一个高级的分布式协调Redis客户端。

7.2 Jedis和Redission相比有什么优缺点

Jedis

  • 轻量,简洁,便于集成和改造

  • 支持连接池

  • 支持pipelining、事务、LUA Scripting、Redis Sentinel、Redis Cluster

  • 不支持读写分离,需要自己实现

  • 文档差

Redission

  • 基于Netty实现,采用非阻塞IO,性能高

  • 支持异步请求

  • 支持连接池

  • 支持pipelining、LUA Scripting、Redis Sentinel、Redis Cluster

  • 不支持事务,官方建议以LUA Scripting代替事务

  • 支持在Redis Cluster架构下使用pipelining

  • 支持读写分离,支持读负载均衡,在主从复制和Redis Cluster架构下都可以使用

  • 内建Tomcat Session Manager,为Tomcat 6/7/8提供了会话共享功能

  • 可以与Spring Session集成,实现基于Redis的会话共享

  • 文档较丰富,有中文文档

https://zhuanlan.zhihu.com/p/272181377open in new window

7.3 有MySQL不就够了吗?为什么还要使用Redis

高性能:我们用MySQL查询数据时,需要从磁盘进行查找,速度是比较慢的,如果我们经常对该值进行查找,则会一遍一遍的请求MySQL数据库,但是如果我们将其存入缓存,再次请求时,因为是直接访问内存,速度是极快,当数据库的内容发生改变时,只需改变缓存的值即可。

高并发:直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以将部分值存到缓存中去,当用户请求时直接从缓存中获取即可。

7.4 为什么不用Guava,而选择Redis做缓存

严格意义上来说,缓存分为分布式缓存和本地缓存。

本地缓存含义为,每个程序实例有一个自己的缓存,其中的内容也不一致,当某个实例结束时缓存也就消失。

Redis和Memcached缓存则是分布式缓存,在多实例的情况下,每个缓存共享一个缓存。具有缓存一致性。这也是它们的优点所在,但是他们也有缺点,就是要保持高可用性。

7.5 Redis和Memcached的区别

  • 类型

    Redis是一个开源的内存数据结构存储系统,用作数据库,缓存和消息代理

    Memcached是一个免费的开源高性能分布式内存对象,通过减少负载来加速动态web应用程序

  • 数据结构

    Redis支持字符串,散列表,列表,集合,有序集,哈希表

    Memcached支持字符串和整数

  • 执行速度

    Memcached的读写速度慢于Redis

  • Value值

    Redis最大512M

    Memcache最大只能1M

https://blog.csdn.net/guoguo527/article/details/108818556open in new window

7.6 Redis为啥那么快?

  • 内存数据库,所有操作都在内存上

  • 高效的数据结构

  • 单线程避免了上下文切换

  • 非阻塞I/O:Redis采用epoll做为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为了时间,不在I/O上浪费过多的时间。

Redis基于Reactor模式开发了网络事件处理器,处理器为文件处理器,然后这个是单线程的,它采用IO多路复用机制(epoll),来监听Socket,根据Socket上的事件,来处理事件,并为其分配相应的事件处理器来处理这个事件。

推荐阅读:https://blog.csdn.net/qq_14855971/article/details/113564022open in new window

7.7 Redis扩容

redis 解决冲突的方法是使用链地址法,另外当容量不足的时候,则使用Rehash 进行扩容。

rehash

给哈希表 2 分配更大的空间,

例如是当前哈希表 1 大小的两倍;

把哈希表 1 中的数据重新映射并拷贝到哈希表 2 中;

释放哈希表 1 的空间。

渐进式rehash则是不一次性拷贝,当访问到某个数据时,再进行拷贝。

7.8 Redis如何实现事务?

事务的生命周期

开启事务(Redis 中使用 MUlTI 来实现)

执行事务中的操作:增删改查等操作,Redis 会将这些操作保存在一个队列中,暂且先不执行

提交事务 EXEC 提交事务

Redis 的事务能保证哪些特性?

原子性

  • 命令入队时就报错,会放弃事务执行,保证原子性;命令入队时没报错,

  • 实际执行时报错,不保证原子性;

  • EXEC 命令执行时实例故障,如果开启了 AOF 日志,可以保证原子性。

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等

Redis 事务满足一致性

隔离性

如果开启了WATCH 机制则没有被破坏,因为其会监控键值对的改变。保证一致性

持久性

不能保证持久性

推荐阅读:https://zhuanlan.zhihu.com/p/135241403open in new window

7.9 Redis的使用场景

缓存:用来保存热点数据

限时业务:因为我们可以设置淘汰时间,比如验证码,登陆时间等

计数器相关

排行榜:我们可以使用zset

点赞共同好友等

消息队列

7.10 脑裂

数据丢失的问题

脑裂:多个主服务器,然后客户端,不知道该写入那个主服务器。则出现了多个客户端写入多个主服务器的情况。

出现原因:主库假失败

脑裂为什么会发生数据丢失?

  • 主库中的数据,未同步到从库,然后此时主库崩溃,则就出现了数据丢失的情况。

  • 主服务器下线之后,有可能从库依旧和原来的主库进行交互,这样会导致新数据,放在不同的主库上。

因为我们此时产生脑裂,然后此时有两个主机,新写的数据会写入两个主机,然后造成两个主机都会保存数据,另外当切换新的主机的时候,原来的主机会清理掉所有数据,然后执行新主机发来的RDB文件,进而出现了数据丢失的情况。

如何防止脑裂,通过配置从库和主库发送ACK消息的延迟时间来解决。

min-slaves-max-lag

7.11 Redis 冲突的怎么办?Rehash,负载因子?

采用链地址法解决冲突,rehash扩容,渐进式rehash,负载因子为大于 1 或 大于 5 的时候进行扩容。