redis知识点

1 redis特色

  内存数据库,读写速度快,被应用于缓存。redis

  数据类型丰富,支持事务、持久化、LUA脚本、LRU驱动事件、多种集群方案。算法

  丰富的特性:缓存,消息,过时,自动删除数据库

2 数据类型:

  hash:k-v集合,适用于存储对象。因为组合式的压缩,内存利用率更高。后端

  字符串:一个键最大能存512MB缓存

  列表:按照插入顺序排序。安全

    异步队列:rpush为生产消息,lpop为消费消息。可是消费者下线时,生产消息会丢失。服务器

  set集合:string类型的无序集合,经过哈希表实现,增删查的复杂度是O(1)。网络

  zset:有序集合,且不重复。数据结构

存储结构:

  redis通信协议RESP格式的命令文本存储。是redis客户端和服务端以前使用的一种通信协议。特色:实现简单、快速解析、可读性好。多线程

4 redis作缓存的缘由

  高性能:

  a 假如用户第一次访问数据库中的某些数据。这个过程会比较慢,由于是从硬盘上读取的。b 将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就能够直接从缓存中获取了。操做缓存就是直接操做内存,因此速度至关快。c 若是数据库中的对应数据改变的以后,同步改变缓存中相应的数据便可

  高并发:

  直接操做缓存可以承受的请求是远远大于直接访问数据库的,因此咱们能够考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用通过数据库。

  分布式缓存:

  使用 redis 或 memcached 之类的称为分布式缓存,在多实例的状况下,各实例共用一份缓存数据,缓存具备一致性。缺点是须要保持 redis 或 memcached服务的高可用,整个程序架构上较为复杂。

单线程redis快速的缘由:

  1.彻底基于内存操做,绝大部分请求是纯粹的内存操做,很是快速。数据存在内存中,查找和操做的时间复杂度都是O(1)

  忽略磁盘操做。

  2.数据结构简单,对数据操做也简单

  3.采用单线程,避免频繁的上下文切换和竞争条件,也不存在多进程或者多线程致使的切换而消耗CPU,不用去考虑各类锁的问题,不存在加锁释放锁操做,没有由于可能出现死锁而致使的性能消耗

  4.采用I/O多路复用机制,非阻塞。

  5.使用底层模型不一样,它们之间底层实现方式以及客户端之间的通讯的应用协议不同,redis直接本身构建了VM机制,由于通常的系统调用系统函数的话,会浪费必定的时间去移动和请求。

6 持久化技术

  持久化就是将内存的数据写到磁盘中,防止宕机时内存数据丢失。

  持久化策略包括RDB(redis database)快照和AOF(append-only file)日志

  RDB是每隔一段时间对redis进行一次持久化,速度快,性能好,可是数据不完整。核心函数有rdbSave为rdb文件和rdbLoad。

  AOF是从新执行命令,数据完整,安全可是速度慢,文件大。主要是调用flushappendonlyfile函数。将aof_buf中的缓存写入到AOF文件,或者是调用fsync、fdatasync函数,将AOF文件保存到磁盘中。

架构模式:单机版和分布式

  单机版:内存容量有限,处理能力有限,没法高可用。

  分布式:主从复制。保证数据相同。没法保证高可用。没有解决master写的压力。

  哨兵:分布式系统中监控redis主从服务器,并在主服务器下线时自动进行故障转移。

    特性:监控:不断地检查主从服务器是否运做正常。

    提醒:当被监控的某个redis服务器出现问题时,哨兵能够经过API向管理员或者其余应用程序发送通知。

    自动故障迁移:当一个主服务器不能正常工做时,哨兵会开始一次自动故障迁移操做。

    特色:保证高可用、监控各个节点、自动故障迁移;主从模式,切换须要时间,可能丢数据,没有解决master写的压力

  集群proxy

    特色:twemproxy,代理服务器,快速的,单线程。

    优势:能够支持多种hash算法,失败节点会自动删除,后端sharding分片逻辑对业务透明,业务方的读写方式和操做单个redis一致。

    缺点:增长新proxy时,须要维护高可用。不支持故障的自动转移。

    须要本身实现failover,扩展性差。手动干预扩容和缩容。

  集群codis:

    和twemproxy效果一致,可是支持在节点数量改变的状况下,旧节点恢复到新hash节点。

  集群直连型:无中心结构,每一个节点保存数据和整个集群状态,每一个节点都和其余节点链接。

    特色:没有中心节点,没有proxy层。

      节点间数据共享,能够动态调整数据分布。

      可扩展,到1000个节点,节点可动态增长或者删除。

      高可用,部分节点不可用时,集群仍然可使用。slave作备份数据。

      实现故障自动failover,节点间经过gossip协议交换状态信息,投票机制完成slave到master的角色提高。

    缺点:资源隔离性差,容易互相影响。

      数据异步复制,不保证数据的一致性。

    hash槽:根据CRC16(key) mod 16384,以为key-value放入哪一个桶(节点)。

8 redis和memcached区别 

  1. redis支持更丰富的数据类型(支持更复杂的应用场景):Redis不只仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持简单的数据类型,String。
  2. Redis支持数据的持久化,能够将内存中的数据保持在磁盘中,重启的时候能够再次加载进行使用,而Memecache把数据所有存在内存之中。
  3. 集群模式:memcached没有原生的集群模式,须要依靠客户端来实现往集群中分片写入数据;可是 redis 目前是原生支持 cluster 模式的.
  4. Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的多路 IO 复用模型。
  5. Memcached相似于一致性哈希的分布式算法实现分布式存储。

    一致性哈希:DHT能够经过减小影响范围的方式,解决增减服务器致使的数据散列问题,解决分布式环境下负载均衡问题。若是存在热点数据,能够经过增添节点的方

 

9 redis设置过时时间

  Redis中有个设置时间过时的功能,即对存储在 redis 数据库中的值能够设置一个过时时间。做为一个缓存数据库,这是很是实用的。如咱们通常项目中的 token 或者一些登陆信息,尤为是短信验证码都是有时间限制的,按照传统的数据库处理方式,通常都是本身判断过时,这样无疑会严重影响项目性能。

  咱们 set key 的时候,均可以给一个 expire time,就是过时时间,经过过时时间咱们能够指定这个 key 能够存活的时间。若是假设你设置了一批 key 只能存活1个小时,那么接下来1小时后,redis是怎么对这批key进行删除的?

  按期删除+惰性删除。

  • 按期删除:redis默认是每隔 100ms 就随机抽取一些设置了过时时间的key,检查其是否过时,若是过时就删除。注意这里是随机抽取的。为何要随机呢?你想想假如 redis 存了几十万个 key ,每隔100ms就遍历全部的设置过时时间的 key 的话,就会给 CPU 带来很大的负载!
  • 惰性删除 :按期删除可能会致使不少过时 key 到了时间并无被删除掉。因此就有了惰性删除。假如你的过时 key,靠按期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,也是够懒的哈!

  可是仅仅经过设置过时时间仍是有问题的。咱们想一下:若是按期删除漏掉了不少过时 key,而后你也没及时去查,也就没走惰性删除,此时会怎么样?若是大量过时key堆积在内存里,致使redis内存块耗尽了。怎么解决这个问题呢? redis 内存淘汰机制。

10 redis内存淘汰机制

 redis 提供 6种数据淘汰策略:

  1. volatile-lru:从已设置过时时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  2. volatile-ttl:从已设置过时时间的数据集(server.db[i].expires)中挑选将要过时的数据淘汰
  3. volatile-random:从已设置过时时间的数据集(server.db[i].expires)中任意选择数据淘汰
  4. allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最经常使用的)
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  6. no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操做会报错。

  4.0版本后增长如下两种:

  1. volatile-lfu:从已设置过时时间的数据集(server.db[i].expires)中挑选最不常用的数据淘汰
  2. allkeys-lfu:当内存不足以容纳新写入数据时,在键空间中,移除最不常常使用的key

11 redis事务(不是原子性)

  Redis 经过 MULTI、EXEC、WATCH 等命令来实现事务(transaction)功能。事务提供了一种将多个命令请求打包,而后一次性、按顺序地执行多个命令的机制,而且在事务执行期间,服务器不会中断事务而改去执行其余客户端的命令请求,它会将事务中的全部命令都执行完毕,而后才去处理其余客户端的命令请求。

  注意:redis同一个事务中若是有一条命令执行失败,其后的命令仍然会被执行,没有回滚。 

12 缓存雪崩和缓存穿透

  缓存雪崩:

    当缓存服务器重启或者大量缓存集中在一个时间段失效,失效时会对后端系统带来很大压力,严重时数据库会宕机。

    避免:

    1.缓存失效后,经过加锁或者队列控制读数据库、写缓存的线程数量。好比某个key只容许一个线程查询数据和写缓存,其余线程等待

    2.作二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,访问A2,A1缓存失效时间短时间,A2为长期

    3.不一样的key设置不一样的过时时间,让缓存失效的时间点尽可能均匀。

  缓存穿透:

    通常的缓存系统是按照key去缓存查询,不存在对应的value时,会去后端系统查询。而恶意的请求会故意查询不存在的key,请求量直接到数据库上,请求量很大时,会对后端系统形成很大压力,就叫缓存穿透。

    正常处理流程:

    解决:

      1.查询结果为空的状况进行缓存过时时间,缓存时间短,最长不超过5分钟,或者key对应的数据插入后清理缓存。

      2.使用布隆过滤器。对必定不存在的key进行过滤。把全部可能存在的key放在一个大的bitmap(哈希表)中,查询时经过bitmap过滤,这样避免了对底层存储系统的查询压力。

13 分布式锁

  缘由

    redis并发竞争key时,多个系统同时对一个 key 进行操做,可是最后执行的顺序和咱们指望的顺序不一样,这样也就致使告终果的不一样!

  先使用setnx抢锁,设置超时时间以释放锁、超过一半的redis实例设置成功,就表示加锁完成。

  注意:若是不存在 Redis 的并发竞争 Key 问题,不要使用分布式锁,这样会影响性能

相关文章
相关标签/搜索