1、使用redis有哪些好处?
1)、速度快,因为数据存在 内存中,类似于HashMap,HashMap优势就是查找和操作的时间复杂度都是o(1)
2)、支持丰富的数据类型:支持string;list;set;sorted;hashMap五种数据类型
3)、支持事务,操作都是原子性。
4)、丰富的特性:可用于缓存、消息、按key设置国企时间,过期后将自动删除
2、redis常见性能问题和解决方案
- Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
- 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
- 为了主从复制的速度和链接的稳定性,Master和Slave最好在同一个局域网内
- 尽量避免在压力很大的主库上增加从裤
- 主从复制不要用图状结构,用单链表结构更为稳定,即
Master <- Slave1 <- Slave2 <- Slave3...
这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
- master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响非常大,会间断性暂停服务,所以Master最好不要写内存快照
- Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
- Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
3、mysql里有2000w数据,redis中只有20w的数据,如何保证redis中的数据都是热点数据
相关知识:redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis提供6中数据淘汰策略:
- voltile-lru:从已设置过期时间的数据集中调谑最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
- allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集中挑选任意数据淘汰
- no-enviction:禁止驱逐数据
4、redis最适合的场景
redis最适合所有数据in-momory的场景,虽然redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家会有疑问,似乎Redis更像一个加强版的Memcached,那么合适使用Memcached,何时使用redis?
如果简单比较redis与memcached的区别,大多数都会得到以下观点:
- redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储
- redis支持数据的备份,即master-slave模式的数据备份
- redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
1)、会话缓存
最常用的一种使用redis的情景是会话缓存。用redis缓存会话比其他存储的优势在于:redis提供持久化。当维护一个不是严格要求一致性的缓存时
2)、全页缓存(FPC)
除基本的会话token之外,redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。
3)、队列
Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
4)、排行榜/计数器
redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:
当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:
ZRANGE user_scores 0 10 WITHSCORES
5)、发布订阅
发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。
Redis提供的所有特性中,我感觉这个是喜欢的人最少的一个,虽然它为用户提供如果此多功能。
6、为什么redis需要将所有数据放到内存中
redis为了达到最快的读写速度将数据读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度会严重影响redis的性能。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值
7、redis的并发竞争问题如何解决
redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。redis本身没有锁的概念。redis对于多个客户端连接并不存在竞争,但是在jedis客户端对redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法
1、客户端角度:为保证每个客户端间正常有序的与redis进行通信,对连接进行池化,同时对客户端读写redis操作采用内部锁
2、服务器角度:利用setnx实现锁
注:对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题。
8、redis事务的了解
redis中事务的实现特征
- 在事务中的所有命令都将会被串行化的顺序执行,在事务执行期间,redis不会再为其他客户端的请求提供热河服务,从未保证了事务中的所有命令被原子的执行
- 和关系型数据库中的事务相比,在redis事务中如果有某一条命令执行失败,其后的命令仍然会被继续执行
- 我们可以通过multi命令开启一个事务,在该语句知乎执行的命令都将被视为事务之内的操作。最后可以通过执行exec/discard命令来提交/回滚该事务内的所有操作
- 在事务开启之前,如果客户端与服务器之间出现通讯故障并导致网络断开,其后所有待执行的语句都将不会被服务器执行。然而如果网络中断事件是发生在客户端执行exec命令之后,那么该事务中的所欲命令都会被服务器执行
- 当使用Append-Only模式时,redis会通过调用系统函数write将该事务内的所欲写操作在本次调用中全部写入磁盘。然而如果在写入的过程中出现系统崩溃,如电源故障的宕机,那么此时也许只有部分数据被写入到磁盘,而另一部分数据已经丢失。redis服务器会在重启时执行一系列必要的检测,一旦发现类似问题,就会立即退出并给出相应的错误提示。此时,我们就要充分利用redis工具包中提供的redis-check-aof工具。该工具可以帮助我们定位到数据不一致的错误,并将已经写入的部分数据进行回滚。修复之后我们就可以再次重启服务器