常用工具
Redis支持的Java客户端都有哪些?官方推荐用哪个?
Redisson、Jedis、lettuce等等,官方推荐使用Redisson。
Redis和Redisson有什么关系?
Redisson是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象 (Bloom filter, BitSet, Set, SetMultimap,
ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。
Jedis与Redisson对比有什么优缺点?
Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。
其他问题
Redis与Memcached的区别
两者都是非关系型内存键值数据库,现在公司一般都是用 Redis 来实现缓存,而且 Redis 自身也越来越强大了!Redis 与 Memcached 主要有以下不同:
对比参数 |
Redis |
Memcached |
类型 |
1. 支持内存 2. 非关系型数据库 |
1. 支持内存 2. 键值对形式 3. 缓存形式 |
数据存储类型 |
1. String 2. List 3. Set 4. Hash 5. Sort Set 【俗称 |
1. 文本型 2. 二进制类型 |
ZSet】
查询【操作】类 |
1. 批量操作 2. 事务支持 3. 每个类型不同的CRUD |
1.常用的CRUD 2. 少量的其他命令 |
型 |
||
附加功能 |
1. 发布/订阅模式 2. 主从分区 3. 序列化支持 4. 脚 |
1. 多线程服务支持 |
本支持【Lua脚本】 |
||
网络IO模型 |
1. 单线程的多路 IO 复用模型 |
1. 多线程,非阻塞IO模式 |
事件库 |
自封转简易事件库AeEvent |
贵族血统的LibEvent事件库 |
持久化支持 |
1. RDB 2. AOF |
不支持 |
集群模式 |
原生支持 cluster 模式,可以实现主从复制,读写 |
没有原生的集群模式,需要依靠客户端来实现 |
分离 |
Memcached 的数据则会一直在内存中,Me
内存管理机制 |
在 Redis 中,并不是所有数据都一直存储在内存 |
特定长度的块来存储数据,以完全解决内存碎 |
中,可以将一些很久没用的 value 交换到磁盘 |
式会使得内存的利用率不高,例如块的大小 |
100 bytes 的数据,那么剩下的 28 by
适用场景 |
复杂数据结构,有持久化,高可用需求,value存储 |
纯key-value,数据量非常大,并发 |
内容较大 |
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis的速度比memcached快很多
(3) redis可以持久化其数据
如何保证缓存与数据库双写时的数据一致性?
你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?
一般来说,就是如果你的系统不是严格要求缓存+数据库必须一致性的话,缓存可以稍微的跟数据库偶尔有不一致的情况,最好不要做这个方案,读请求和写请求串行化,串到一个内存队列里去,这样就可以保证一定不会出现不一致的情况串行化之后,就会导致系统的吞吐量会大幅度的降低,用比正常情况下多几倍的机器去支撑线上的一个请求。
还有一种方式就是可能会暂时产生不一致的情况,但是发生的几率特别小,就是先更新数据库,然后再删除缓存。
问题场景 |
描述 |
解决 |
先写缓存,再写数据库,缓存 缓存写成功,但写数据库失败或者响应延迟,则下次读取 这个写缓存的方式,本身就是错误的,需要改为先写数据
写成功,数据库写失败 |
(并发读)缓存时,就出现脏读 |
库,把旧缓存置为失效;读 |
在,则读取数据库再写缓存
先写数据库,再写缓存,数据 |
写数据库成功,但写缓存失败,则下次读取(并发读)缓 |
缓存使用时,假如读缓存失 |
库写成功,缓存写失败 |
存时,则读不到数据 |
方式实现 |
需要缓存异步刷新 |
指数据库操作和写缓存不在一个操作步骤中,比如在分布 |
确定哪些数据适合此类场景 |
式场景下,无法做到同时写缓存或需要异步刷新(补救措 |
||
一致时间,用户数据刷新的时间 |
||
施)时候 |
Redis常见性能问题和解决方案?
1. Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。
2. 如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
3. 为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。
4. 尽量避免在压力较大的主库上增加从库
5. Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。6. 为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变。
Redis官方为什么不提供Windows版本?
因为目前Linux版本已经相当稳定,而且用户量很大,无需开发windows版本,反而会带来兼容性等问题。
一个字符串类型的值能存储最大容量是多少?
512M
Redis如何做大量数据插入?
Redis2.6开始redis-cli支持一种新的被称之为pipe mode的新模式用于执行大量数据插入工作。
假如Redis里面有1亿个key,其中有10w个key是以某个
固定的已知的前缀开头的,如果将它们全部找出来?
使用keys指令可以扫出指定模式的key列表。
对方接着追问:如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?
这个时候你要回答redis关键的一个特性:redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。
使用Redis做过异步队列吗,是如何实现的
使用list类型保存数据信息,rpush生产消息,lpop消费消息,当lpop没有消息时,可以sleep一段时间,然后再检查有没有信息,如果不想sleep的话,可以使用blpop, 在没有信息的时候,会一直阻塞,直到信息的到来。redis可以通过pub/sub主题订阅模式实现一个生产者,多个消费者,当然也存在一定的缺点,当消费者下线时,生产的消息会丢失。
Redis如何实现延时队列
使用sortedset,使用时间戳做score, 消息内容作为key,调用zadd来生产消息,消费者使用zrangbyscore获取n秒之前的数据做轮询处理。
Redis回收进程如何工作的?
1. 一个客户端运行了新的命令,添加了新的数据。
2. Redis检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。