【本文内容来自网络总结】
Redis是一个开源、高性能、基于键值对的缓存与存储系统。
劣势:Redis是单线程,Memcached是多线程,在多核服务器上后者的性能理论上会更高一些。 优势:随着Redis3.0的推出,标志着memcache的所有功能都已经成了Redis的子集。同时Redis对集群的支持使得Memcache原有的第三方集群工具不再成为优势。因此,在新项目中使用Redis替代Memcache将会是非常好的选择。
(1)字符串类型 (Key-Value) 使用最多的类型 (2)散列类型 (Hash) 适合存储对象 (3)列表类型 (List) (4)集合类型 (Set) (5)有序集合类型 (Zset)
内存
Remote Dictionary Server(远程数据服务)
共六种数据淘汰策略。(分三类) 一、从已设置过期的数据集 (1)volatile-lru:从已设置过期时间的数据集中,选择最近最少使用的数据淘汰 (2)volatile-ttl:从已设置过期时间的数据集中,选择将要过期的数据淘汰 (3)volatile-random:从已设置过期时间的数据集中,任意选择数据淘汰 二、从整体数据集 (4)allkeys-lru:从全数据集中,选择最近最少使用的数据淘汰 (5)allkeys-random:从全数据集中任意选择数据淘汰 三、驱逐(默认策略-直接返回错误) (6)noenviction(驱逐):不删除任意数据(但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误
目前Linux版本已经相当稳定,用户量很大,无需开发windows版本,反而会带来兼容性等问题。
512M。
内存存取远比磁盘IO快得多。
(1)Twemproxy,推特的开源方案。它会以一个代理的身份接收请求并使用一致性hash算法,将请求转接到具体redis,将结果再返回twemproxy。 问题:redis节点数量改变时候,数据无法自动移动到新的节点。 (2)Codis,豌豆荚的开源方案。目前使用最多的集群方案,基本和twemproxy一致的效果,它支持在 节点数量改变情况下,旧节点数据可恢复到新hash节点。 (3)Redis cluster3.0自带的集群,特点:他的分布式算法不是一致性hash,而是hash槽,以及自身支持节点设置从节点。 (4)业务代码层实现,在代码层,对key 进行hash计算,然后去对应的redis实例操作数据。 这种方式对hash层代码要求比较高,需要重点考虑的是,节点失效后的替代算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。
有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会因为缺少5501-11000这个范围的槽而不可用。数据丢失
先计算下这20W条数据占用的内存,设置最大可用内存,当内存中的数据集达到上限时,redis就会启动LRU(数据淘汰策略)。
(1)会话缓存(Session Cache) 例如:分布式登录信息,购物车信息,能提供持久化。 (2)全页缓存(FPC) 除基本的会话token之外,Redis还提供很简便的FPC平台。即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降 (3)队列 由于支持 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用 (4)排行榜/计数器 incr range (5)发布/订阅
Redisson、Jedis等等,官方推荐使用Redisson。
Redisson 是一个高级的、分布式协调Redis客户端。
(1)Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持; (2)Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。 (3)Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。
设置密码:两种方式 需重启redis:打开redis.conf中的 requirepass foobared 不重启redis: config set requirepass 123456 验证密码:两种方式 方式一、登录的时候验证 例如:redis-cli -h 127.0.0.1 -p 6379 -a cfadata@2016 方式二、登录时不指定密码,而在执行操作前进行认证。使用auth 命令认证。
1、Redis 集群中内置了 16384 个哈希槽。 2、需要在 Redis 集群中存一个 key-value时,Redis 先对 key 使用 crc16 算法算出一个结果。 3、然后把结果对 16384 取模,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽。 4、Redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品
Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下(使用的内存超过了最大可用内存(数据淘汰策略是noenviction(驱逐)的时候))可能会丢失写操作。
异步复制 初始化复制: (1)从数据库启动后,会向主数据库发送SYNC命令。 (2)主数据库收到SYNC后会在后台保存快照(RDB持久化过程),并将保存快照期间接收到的命令缓存起来。 (3)快照完成后,Redis会将快照文件和所有缓存的命令发送给从数据库。 (4)从数据库收到快照后会载入快照文件并执行缓存命令。 运行中复制: 当主数据库每当收到写命令,就会将命令同步到从数据库。 断线重连机制: redis2.6之前,断线重连后会进行全部复制(主数据库的RDB文件发给从数据库) redis2.8之后,断线重连后进行的是增量复制。
16384个,但是建议最多有1000个节点。
默认在0号数据库。
ping命令测试客户端与redis服务连接是否正常,返回pong正常。
可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
(1) 提供了命令打包,顺序执行的机制。 (2) 命令入队,先进先出。 (3) 带 WATCH 命令的事务,当键对应的值被修改时,事务直接返回失败,否则成功。 (5) 保证了一致性和隔离性,不保证原子性和持久性(Redis的事务不是一个完整的事务)。 参考: 深入理解Redis事务
1、MULTI (开启事务) 2、DISCARD (取消事务,如果正在使用 WATCH 命令监视某个(或某些) key,那么取消所有监视,等同于执行命令 UNWATCH) 3、EXEC (执行事务) 4、WATCH (监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断)
1、过期时间:set key timeout value 2、永久有效:默认不设置过期时间(set key value)永久有效,但是如果实际使用内存超过你设置的最大内存,并且设置了数据淘汰策略,就会使用LRU删除机制
应使用散列表(HashSst),适合存储对象类型。尽可能的将数据模型抽象到一个散列表里面。比如:用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面。
1、客户端接收到数据写入请求后,Redis检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。一个新的命令被执行。 2、所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。
LRU算法。
Redis2.6开始redis-cli支持一种新的被称之为pipe mode的新模式用于执行大量数据插入。
分区使得我们本来受限于单台计算机硬件资源的问题不再是问题,存储不够,计算资源不够,带宽不够,我们都可以通过增加机器来解决这些问题。
1、客户端分区:就是在客户端就已经决定数据会被存储到哪个redis节点或者从哪个redis节点读取。大多数客户端已经实现了客户端分区。 2、代理分区 :意味着客户端将请求发送给代理,然后代理决定去哪个节点写数据或者读数据。代理根据分区规则决定请求哪些Redis实例,然后根据Redis的响应结果返回给客户端。redis和memcached的一种代理实现就是Twemproxy 3、查询路由(Query routing) :意思是客户端随机地请求任意一个redis实例,然后由Redis将请求转发给正确的Redis节点。Redis Cluster实现了一种混合形式的查询路由,但并不是直接将请求从一个redis节点转发到另一个redis节点,而是在客户端的帮助下直接redirected到正确的redis节点。
1、多键操作是不被支持的,比如我们将要批量操作的键被映射到了不同的Redis实例中。 2、多键的Redis事务是不被支持的。 3、分区的最小粒度是键,因此我们不能将关联到一个键的很大的数据集映射到不同的实例。 4、当应用分区的时候,数据的处理是非常复杂的,比如我们需要处理多个rdb/aof文件,将分布在不同实例的文件聚集到一起备份。 5、添加和删除机器是很复杂的,例如Redis集群支持几乎运行时透明的因为增加或减少机器而需要做的rebalancing,然而像客户端和代理分区这种方式是不支持这种功能的。
1、如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。 2、如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。
1、一开始就做分区,迁移redis实例不用考虑分区 2、既然Redis是如此的轻量(单实例只使用1M内存),为防止以后的扩容,最好的办法就是一开始就启动较多实例。即便你只有一台服务器,你也可以一开始就让Redis以分布式的方式运行,使用分区,在同一台服务器上启动多个实例。 这样的话,当你的数据不断增长,需要更多的Redis服务器时,你需要做的就是仅仅将Redis实例从一台服务迁移到另外一台服务器而已(而不用考虑重新分区的问题)。一旦你添加了另一台服务器,你需要将你一半的Redis实例从第一台机器迁移到第二台机器。
Twemproxy 是一个Twitter开源的一个redis和memcache快速/轻量级代理服务器;可以将其后端的多台redis或memcached实例进行统一管理与分配,使应用程序只需要在Twemproxy 上进行操作,而不用关心后面具体有多少个真实的redis或memcached存储。
Redis-rb、Predis等。
1、Redis有复杂的数据结构并且提供对他们的原子性操作。 2、Redis的数据类型都是基本数据结构的同时对程序员透明,无需进行额外的抽象。 3、Redis运行在内存中但是可以持久化到磁盘。 4、相同复杂的数据结构,在内存中操作比在磁盘操作更简单。 5、磁盘格式方面是紧凑的以追加的方式产生的,并不需要进行随机访问。
利用Hash,List,Set,Sorted set(zset) 等集合类型数据,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起。
INFO
1、默认:如果达到设置的上限,写命令会返回错误信息(但是读命令还可以正常返回) 2、配置淘汰机制:当Redis达到可用内存上限时会冲刷掉旧的数据。
1、可以在同一个服务器部署多个Redis的实例,并把他们当作不同的服务器来使用。 2、如果你想使用多个CPU,你可以考虑一下分片(shard)。
理论上Redis可以处理2的32次方keys,任何list、set、和sorted set都可以放2的32次方个元素。
1、 Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件 2、如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次 3、为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内 4、避免在压力很大的主库上增加从库 5、主从复制不要用网状结构(类似n-1结构),用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。
提供了两种持久化方式:AOF和RDB 区别是: AOF:append only file aof是将Redis执行的每一条命令追加到硬盘文件中(保存的执行命令) RDB:rdb是通过快照的方式将符合条件的数据持久化到硬盘(保存的是命令执行后得到的数据) 持久化配置规则: save 900 20 (意思是900秒内 有超过20条数据写入或修改,就会执行持久化操作)
1、如果想达到足以媲美PostgreSQL的数据安全性, 你应该同时使用两种持久化功能。 2、如果非常关心数据, 但仍然可以承受数分钟以内的数据丢失,那么可以只使用RDB持久化。 3、有很多用户都只使用AOF持久化,但并不推荐这种方式:因为定时生成RDB快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快。
Config Set 命令可以动态地调整 Redis 服务器的配置而无须重启。
1、根据配置规则进行自动快照。 2、用户执行save或者bgsave命令。 3、执行flushall命令。 4、执行复制(replication)时。
1、什么是缓存击穿? 查询一个在缓存中必然不存在的数据,导致每次请求都要在数据库中查询。 2、没缓存和没有缓存的的系统吞吐量有多大的差别? 没有用缓存时,mysql的并发数在300(机械硬盘)-700(固态硬盘)之间(高性能服务器)。一般的笔记本200个连接都撑不住。
1、对空值也做缓存,过期时间设置较短 2、对不符合规则的查询值做过滤 3、用bitMap和布隆过滤器 4、设置KEY为不同的过期时间 缓存失效: 产生原因:设置缓存失效的时间过于集中,导致缓存在同一时刻大面积失效。 解决办法:可以为不同的key设置为不同的过期时间。 缓存穿透: 产生原因:查询一个在缓存中必然不存在的数据,导致每次请求都要在数据库中查询。 解决办法:1、对不符合规则的查询值做过滤 2、用bitMap和布隆过滤器 3、空值也做缓存 缓存雪崩: 产生原因:缓存雪崩就是指由于缓存的原因,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难。“缓存并发”,“缓存穿透”,“缓存颠簸”等问题,其实都可能会导致缓存雪崩现象发生。 解决办法:从应用架构角度,我们可以通过限流、降级、熔断等手段来降低影响,也可以通过多级缓存来避免这种灾难。
连接:如何搭建高可用的redis服务 (Redis高可用架构的演变)
1、数据结构简单 2、单线程无CPU切换性能损耗 3、没有多线程加锁问题
线程安全的。(单线程没有线程安全一说)
缓存一致性问题 缓存并发 缓存颠簸问题 缓存失效 缓存穿透 缓存的雪崩现象 缓存无底洞现象
。。。
四种实现方式: 1、推特的开源框架 twemproxy 代理 2、豌豆荚的 codis 代理 旧的数据可以映射到新的节点 3、Redis自带的集权 Redis cluster3.0 使用的是hash槽 4、代码层面实现 注意数据震荡后的数据恢复 寻址方式: