Redis复习总结(一)

为何选用redis?

因为传统的关系型数据库如mysql已经不能适用所有的场景了,比如秒杀的库存扣减,app首页的访问流量高峰等等,都很容易吧数据库打崩,所以引入了缓存中间件,目前市面上比较常用的缓存中间件有redis和memcached不过中和考虑了他们的优缺点,最后选择了redis。

Redis的数据结构有哪些?
String,Hash,List,Set,SortedSet。

加分:HyperLogLog,Geo,Pub/Sub,RedisModule,BloomFilter,RedisSearch,Redis-ML。

Redis的命令?

keys:获取指定模式的key值,(阻塞式)比如:keys * 获取所有key值,keys pattern。

scan:获取key值,(无阻塞式)比如:scan 0 获取所有key值。

缓存穿透:

概念:黑客恶意调用接口,传递一个redis中没有的key值参数,这样就直接访问到了你的数据库,给你的数据库增加压力。(就是绕过了redis缓存)

解决:

  1. 做参数校验,在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接return,比如:id做基础校验,id<=0的直接拦截等。
  2. 缓存穿透说白了就是要查询的数据不存在(redis和数据库中),那么我们可以将该key-value的value值写为null或者稍后重试等,具体问产品,当然还得设置过期时间,比如:30秒。
  3. 还可以在nginx层做好配置,让运维限制单个ip每秒的访问次数,超出阈值的都拉进黑名单。布隆过滤器(Bloom Filter)这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。那又有小伙伴说了如果黑客有很多个IP同时发起攻击呢?这点我一直也不是很想得通,但是一般级别的黑客没这么多肉鸡,再者正常级别的Redis集群都能抗住这种级别的访问的,小公司我想他们不会感兴趣的。把系统的高可用做好了,集群还是很能顶的。

缓存雪崩:

概念:即redis中大面积的key值同时失效,这时候又有大量的请求打进来,缓存失效那么会直接打到数据库中,这样会把数据库直接打废。就算重启数据库,重新启动的数据库也会立马被新的流量给打死了。(就是大面积的key值同时失效或在很短的时间内失效导致大量的请求访问数据库致使压力过大,整的数据库崩盘)

解决:

  1. 在往redis中批量存数据时,设置过期时间随机值,避免key值失效时间过于集中。
  2. 设置热点数据永不过期,该数据有更新操作的时候更新缓存就好了。

缓存击穿:

概念:和缓存雪崩有点像,但是又有一点不一样,缓存雪崩是指大面积的缓存失效打崩了db,而缓存击穿是指一个热点key不停的扛着大并发,大并发集中对这一个点进行访问,当这个key失效时,持续的大并发就穿破缓存,直接请求到了数据库。

解决:

  1. 设置热点数据永远不过期,当改数据有更新操作的话更新缓存就好了
  2. 给热点key加互斥锁

代码如下:

 

Redis为啥那么快:

 

Redis集群的Sentinel哨兵模式:(需要安装哨兵集群)

因为当主从模式下的redis集群的主节点挂掉后,那么整个集群就没有可以写的节点了,因为从节点备份了主节点全部的数据,那么从节点可不可以升级为主节点,那么哨兵的任务就是这个操作,当主节点挂掉后,将从节点升级为主节点,并且通知挂掉的主节点的其他从节点主节点的地址变了,以及当客户端尝试连接失效的主服务器的时候,集群也会像客户端返回新的主服务器的地址,这个过程也叫自动故障迁移。当原来的主节点(挂掉的主节点)重新上线后,会成为当前主节点的从节点。

哨兵的任务:

1.监控:负责监控 Redis master 和 slave 进程是否正常工作。

2.提醒:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警  通知给管理员。

3.自动故障迁移:如果 master node 挂掉了,会自动转移到 slave node 上。

4.配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。

集群故障投票(半数原则):

当哨兵节点有超过一半的认为某主节点宕机,则该主节点宕机挂掉了,开始执行故障迁移操作。

RedisCluster集群概念:(未安装哨兵集群,非哨兵模式)

(1)由多个Redis服务器组成的分布式网络服务集群;

(2)集群之中有多个Master主节点,每一个主节点都可读可写;

(3)节点之间会互相通信,两两相连;

(4)Redis集群无中心节点。

故障转移:

集群的主节点来投票,超过半数认为某主节点挂掉,则该主节点挂掉了。和哨兵的投票机制一样。

Redis集群分片策略:

Redis-cluster分片策略,是用来解决key存储位置的。集群将整个数据库分为16384个槽位slot,所有key-value数据都存储在这些slot中的某一个上。一个slot槽位可以存放多个数据,key的槽位计算公式为:slot_number=crc16(key)%16384,其中crc16为16位的循环冗余校验和函数。集群中的每个主节点都可以处理0个至16383个槽,当16384个槽都有某个节点在负责处理时,集群进入上线状态,并开始处理客户端发送的数据命令请求。

 

 

Redis集群转向:

由于Redis集群无中心节点,请求会随机发给任意主节点;主节点只会处理自己负责槽位的命令请求,其它槽位的命令请求,该主节点会返回客户端一个转向错误;客户端根据错误中包含的地址和端口重新向正确的负责的主节点发起命令请求

Redis的持久化:

方式1:RDB:RDB 持久化机制,是对 Redis 中的数据执行周期性的持久化。

方式2:AOF:AOF 机制对每条写入命令作为日志,以 append-only 的模式 写入一个日志文件中,因为这个模式是只追加的方式,所以没有任何磁盘寻址的 开销,所以很快,有点像Mysql中的binlog。

两种方式都可以把Redis内存中的数据持久化到磁盘上,然后再将这些数据 备份到别的地方去,RDB更适合做冷备,AOF更适合做热备,比如我杭州的某电 商公司有这两个数据,我备份一份到我杭州的节点,再备份一个到上海的,就算 发生无法避免的自然灾害,也不会两个地方都一起挂吧,这灾备也就是异地容灾, 地球毁灭他没办法。

tip:两种机制全部开启的时候,Redis在重启的时候会默认使用AOF去重新构建数据,因为AOF的数据是比RDB更完整的。

RDB方式持久化:

优点:他会生成多个数据文件,适合做冷备,完整的数据运维设置定时任务,定时同步数据到远端的服务器,这样服务挂了也不怕,想恢复多少分钟之前的数据,只需要去拷贝一份之前的数据文件就可以了。

RDB对Redis的性能影响非常小,是因为在同步数据的时候他只是fork 了一个子进程去做持久化的,而且他在数据恢复的时候速度比AOF来的快。

缺点:RDB都是快照文件,都是默认五分钟甚至更久的时间才会生成一次,这意味着你这次同步到下次同步这中间五分钟的数据都很可能全部丢失掉。AOF则最多丢一秒的数据,数据完整性上高下立判。还有就是RDB在生成数据快照的时候,如果文件很大,客户端可能会暂停几毫秒甚至几秒,你公司在做秒杀的时候他刚好在这个时候fork了一个子进程去生成一个大快照,哦豁,出大问题。

AOF方式持久化:

优点:上面提到了,RDB五分钟一次生成快照,但是AOF是一秒一次去通过一个后台的线程fsync操作,那最多丢这一秒的数据。

AOF在对日志文件进行操作的时候是以append-only的方式去写的,他只是追加的方式写数据,自然就少了很多磁盘寻址的开销了,写入性能惊人,文件也不容易破损。

AOF的日志是通过一个叫非常可读的方式记录的,这样的特性就适合做灾难性数据误删除的紧急恢复了,比如公司的实习生通过flushall清空了所有的数据,只要这个时候后台重写还没发生,你马上拷贝一份AOF日志文件,把最后一条flushall命令删了就完事了。

缺点:一样的数据,AOF文件比RDB还要大。

AOF开启后,Redis支持写的QPS会比RDB支持写的要低,他不是每秒都要去异步刷新一次日志嘛fsync,当然即使这样性能还是很高,我记得ElasticSearch也是这样的,异步刷新缓存区的数据去持久化,为啥这么做呢,不直接来一条怼一条呢,那我会告诉你这样性能可能低到没办法用的。

Redis数据备份:

单独用RDB你会丢失很多数据,你单独用AOF,你数据恢复没RDB来的快,真出什么时候第一时间用RDB恢复,然后AOF做数据补全,冷备热备一起上,才是互联网时代一个高健壮性系统的王道。

保证集群的高可用:

哨兵+主从并不能保证数据不丢失,但是可以保证集群的高可用。

主从之间的数据同步:

为啥要用主从这样的架构模式,前面提到了单机QPS是有上限的,而且Redis的特性就是必须支撑读高并发的,那你一台机器又读又写,这谁顶得住啊,不当人啊!但是你让这个master机器去写,数据同步给别的slave机器,他们都拿去读,分发掉大量的请求那是不是好很多,而且扩容的时候还可以轻松实现水平扩容。

启动一台slave 的时候,他会发送一个psync命令给master ,如果是这个slave第一次连接到master,他会触发一个全量复制。master就会启动一个线程,生成RDB快照,还会把新的写请求都缓存在内存中,RDB文件生成后,master会将这个RDB发送给slave的,slave拿到之后做的第一件事情就是写进本地的磁盘,然后加载进内存,然后master会把内存里面缓存的那些新命令都发给slave。传输过程中有什么网络问题啥的,会自动重连的,并且连接之后会把缺少的数据补上的。

大家需要记得的就是,RDB快照的数据生成的时候,缓存区也必须同时开始接受新请求,不然你旧的数据过去了,你在同步期间的增量数据咋办?是吧

 

内存淘汰机制:

Redis的过期策略有两种,定期删除和惰性删除两种。

定期删除:默认100ms就随机抽一些设置了过期时间的key,去检查是否过期,过期了就删了。

惰性删除:见名知意,惰性嘛,我不主动删,我懒,我等你来查询了我看看你过期没,过期就删了还不给你返回,没过期该怎么样就怎么样。

淘汰机制:

·  noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)

·  allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。

·  volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。

·  allkeys-random: 回收随机的键使得新添加的数据有空间存放。

·  volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。

·  volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

·  如果没有键满足回收的前提条件的话,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。

Redis中还有个LRU,过于复杂不详细解释了,

LRU:LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰

Redis的数据类型的使用场景:

String数据类型:最简单的类型,就是普通的set和get,做简单的KV缓存。

但是在真实的开发环境中很多人可能会把很多比较复杂的结构也同意转成String去存储使用,比如有的人他就喜欢把对象或者List转换为JSONString进行存储,在拿出来反序列化啥的,该方式没有对错,只是希望我们可以在最合适的场景使用最合适的数据,也更为了代码的规范。

String的实际应用场景比较广泛:

  1. 缓存功能,String字符串是最常用的数据类型,不仅仅是redis,各个语言都是最基本类型,因此,利用redis作为缓存,配合其他数据库作为存储层,利用redis支持高并发的特点,可以大大加快系统的读写速度,以及降低后端数据库的压力。
  2. 计数器:许多系统都会使用redis作为系统的实时计数器,可以快速实现计数和查询的功能,而且最终的数据结果可以按照特定的时间落地到数据库或者其他存储介质当中警醒永久保存。
  3. 共享用户session:用户重新刷新一次界面,可能需要访问以下数据进行重新登录,或者访问页面缓存Cookie,但是可以利用Redis将用户的session集中管理,在这种模式只需要保证Redis的高可用,每次用户Session的更新和获取都可以快速完成,大大提高效率。

Hash数据类型:

这个是类似Map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(该对象没嵌套其他的对象)给缓存在Redis中,然后每次读写缓存的时候,就可以操作hash里的某个字段。该类型的使用场景比较单一了一些,因为现在很多对象都是比较复杂的,比如我的工作事项对象里面就包含了很多属性,其中还有对象两个。个人使用场景不是很多。

 

List数据类型:

List是有序列表,这个还是可以玩出很多花样的,看你怎么用了。

比如可以通过list存储一些列表型的数据结构,类似粉丝列表,文章的评论列表之类的东西。

比如可以通过lrange命令,读取某个闭区间内的元素,可以基于list实现分页查询,这个是很棒的一个功能,基于redis实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走。还可以搞个简单的消息队列,从list头进去,从list结尾处弄出来,先进先出,后进后出。该类型使我们比较常用的数据结构了,热点数据也是经常用的。

  1. 消息队列:redis的链表结构,可以轻松实现阻塞队列,可以使用左进左出的命令组成来完成队列的设计。比如:数据的生产者可以通过Lpush命令从左边插入数据,多个数据消费者,可以使用BRpop命令阻塞的“抢”列表尾部的数据。
  2. 文档列表或者数据分页展示的应用:

比如,我们常用的博客网站的文章列表,当用户量越来越多时,而且每一个用户都有自己的文章列表,而且当文章多时,都需要分页展示,这时可以考虑使用redis的列表,列表不但有序同时还支持按照范围内获取元素,可以完美解决分页查询功能,大大提高查询效率。

Set数据类型:

Set是无序集合,会自动去重。

直接基于 Set 将系统里需要去重的数据扔进去,自动就给去重了,如果你需要对一些数据进行快速的全局去重,你当然也可以基于 JVM 内存里的 HashSet 进行去重,但是如果你的某个系统部署在多台机器上呢?得基于Redis进行全局的 Set 去重。

可以基于 Set 玩儿交集、并集、差集的操作,比如交集吧,我们可以把两个人的好友列表整一个交集,看看俩人的共同好友是谁?对吧。

反正这些场景比较多,因为对比很快,操作也简单,两个查询一个Set搞定。

Sorted Set数据类型:

Sorted set是排序的set,去重但可以排序,写进去的时候给一个分数,自动根据分许排序。

有序集合的使用场景与集合类似,但是set集合不是自动有序的,而Sorted set可以利用分数进行成员间的排序,而且是插入时就排序好。所以当你需要一个有序且不重复的集合列表时,就可以选择Sorted set数据结构作为选择方案。

排行榜:有序集合经典使用场景。例如视频网站需要对用户上传的视频做排行榜,榜单维护可能是多方面:按照时间、按照播放量、按照获得的赞数等。

Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。

微博热搜榜,就是有个后面的热度值,前面就是名称。

 

多个系统同时操作(并发)redis带来的数据问题:

 

问题:系统A,B,C,分别去操作redis的同一个key,本来顺序是1,2,3,但是因为系统A网络抖动了一下,B,C系统在他前面操作了redis,这样数据不就错了么。

解决:

 

某个时刻,多个系统实例都去更新某个 key。可以基于 Zookeeper 实现分布式锁。每个系统通过 Zookeeper 获取分布式锁,确保同一时间,只能有一个系统实例在操作某个 Key,别人都不允许读和写。

你要写入缓存的数据,都是从 MySQL 里查出来的,都得写入 MySQL 中,写入 MySQL 中的时候必须保存一个时间戳,从 MySQL 查出来的时候,时间戳也查出来。

每次要写之前,先判断一下当前这个 Value 的时间戳是否比缓存里的 Value 的时间戳要新。如果是的话,那么可以写,否则,就不能用旧的数据覆盖新的数据。

当缓存与数据库双存储双写的时候,如何解决一致性问题?

一般来说,如果允许缓存可以稍微的跟数据库偶尔有不一致的情况,也就是说如果你的系统不是严格要求 “缓存+数据库” 必须保持一致性的话,最好不要做这个方案,即:读请求和写请求串行化,串到一个内存队列里去。

串行化可以保证一定不会出现不一致的情况,但是它也会导致系统的吞吐量大幅度降低,用比正常情况下多几倍的机器去支撑线上的一个请求。

把一些列的操作都放到队列里面,顺序肯定不会乱,但是并发高了,这队列很容易阻塞,反而会成为整个系统的弱点,瓶颈

 

KV,DB读写模式:

最经典的缓存+数据库读写的模式,就是 Cache Aside Pattern

1.读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。

2.更新的时候,先更新数据库,然后再删除缓存

为何是删除缓存,而不是更新缓存?

原因很简单,很多时候,在复杂点的缓存场景,缓存不单单是数据库中直接取出来的值。

比如可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据并进行运算,才能计算出缓存最新的值的。

另外更新缓存的代价有时候是很高的。是不是说,每次修改数据库的时候,都一定要将其对应的缓存更新一份?也许有的场景是这样,但是对于比较复杂的缓存数据计算的场景,就不是这样了。如果你频繁修改一个缓存涉及的多个表,缓存也频繁更新。但是问题在于,这个缓存到底会不会被频繁访问到?

举个栗子:一个缓存涉及的表的字段,在 1 分钟内就修改了 20 次,或者是 100 次,那么缓存更新 20 次、100 次;但是这个缓存在 1 分钟内只被读取了 1 次,有大量的冷数据

实际上,如果你只是删除缓存的话,那么在 1 分钟内,这个缓存不过就重新计算一次而已,开销大幅度降低。用到缓存才去算缓存。

其实删除缓存,而不是更新缓存,就是一个 Lazy 计算的思想,不要每次都重新做复杂的计算,不管它会不会用到,而是让它到需要被使用的时候再重新计算。

MybatisHibernate,都有懒加载思想。查询一个部门,部门带了一个员工的 List,没有必要说每次查询部门,都里面的 1000 个员工的数据也同时查出来啊。80% 的情况,查这个部门,就只是要访问这个部门的信息就可以了。先查部门,同时要访问里面的员工,那么这个时候只有在你要访问里面的员工的时候,才会去数据库里面查询 1000 个员工。

Redis和Memcached的区别,为何选用redis:

Redis 支持复杂的数据结构:

Redis 相比 Memcached 来说,拥有更多的数据结构,能支持更丰富的数据操作。如果需要缓存能够支持更复杂的结构和操作, Redis 会是不错的选择。

Redis 原生支持集群模式:

在 redis3.x 版本中,便能支持 Cluster 模式,而 Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据。

性能对比:

由于 Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更高。而在 100k 以上的数据中,Memcached 性能要高于 Redis,虽然 Redis 最近也在存储大数据的性能上进行优化,但是比起 Remcached,还是稍有逊色。

Redis的线程模型:

Redis 内部使用文件事件处理器 file event handler,这个文件事件处理器是单线程的,所以 Redis 才叫做单线程的模型。它采用 IO 多路复用机制同时监听多个 Socket,根据 Socket 上的事件来选择对应的事件处理器进行处理。

文件事件处理器的结构包含 4 个部分:

1.多个 Socket

2.IO 多路复用程序

3.文件事件分派器

4.事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

多个 Socket 可能会并发产生不同的操作,每个操作对应不同的文件事件,但是 IO 多路复用程序会监听多个 Socket,会将 Socket 产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理。

 

 

Redis的知识点结构:

 

 

 

 

补充:

缓存的知识点结构:

 

缓存有哪些类型?

缓存是高并发场景下提高热点数据访问性能的一个有效手段,在开发项目时会经常使用到。

缓存的类型分为:本地缓存分布式缓存多级缓存

本地缓存:

本地缓存就是在进程的内存中进行缓存,比如我们的 JVM 堆中,可以用 LRUMap 来实现,也可以使用 Ehcache 这样的工具来实现。

本地缓存是内存访问,没有远程交互开销,性能最好,但是受限于单机容量,一般缓存较小且无法扩展。

分布式缓存:

分布式缓存可以很好得解决这个问题。

分布式缓存一般都具有良好的水平扩展能力,对较大数据量的场景也能应付自如。缺点就是需要进行远程请求,性能不如本地缓存。

多级缓存:

为了平衡这种情况,实际业务中一般采用多级缓存,本地缓存只保存访问频率最高的部分热点数据,其他的热点数据放在分布式缓存中。

在目前的一线大厂中,这也是最常用的缓存方案,单考单一的缓存方案往往难以撑住很多高并发的场景。

淘汰策略

不管是本地缓存还是分布式缓存,为了保证较高性能,都是使用内存来保存数据,由于成本和内存限制,当存储的数据超过缓存容量时,需要对缓存的数据进行剔除。

一般的剔除策略有 FIFO 淘汰最早数据、LRU 剔除最近最少使用、和 LFU 剔除最近使用频率最低的数据几种策略。

  • noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)
  • allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
  • volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
  • allkeys-random: 回收随机的键使得新添加的数据有空间存放。
  • volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
  • volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

如果没有键满足回收的前提条件的话,策略volatile-lruvolatile-random以及volatile-ttl就和noeviction 差不多了。

其实在大家熟悉的LinkedHashMap中也实现了Lru算法的,实现如下:

 

 

当容量超过100时,开始执行LRU策略:将最近最少未使用的 TimeoutInfoHolder 对象 evict 掉。

真实面试中会让你写LUR算法,你可别搞原始的那个,那真TM多,写不完的,你要么怼上面这个,要么怼下面这个,找一个数据结构实现下Java版本的LRU还是比较容易的,知道啥原理就好了。

 

 

Memcache

注意后面会把 Memcache 简称为 MC。

先来看看 MC 的特点:

  • MC 处理请求时使用多线程异步 IO 的方式,可以合理利用 CPU 多核的优势,性能非常优秀;
  • MC 功能简单,使用内存存储数据;
  • MC 的内存结构以及钙化问题我就不细说了,大家可以查看官网了解下;
  • MC 对缓存的数据可以设置失效期,过期后的数据会被清除;
  • 失效的策略采用延迟失效,就是当再次使用数据时检查是否失效;
  • 当容量存满时,会对缓存中的数据进行剔除,剔除时除了会对过期 key 进行清理,还会按 LRU 策略对数据进行剔除。

另外,使用 MC 有一些限制,这些限制在现在的互联网场景下很致命,成为大家选择RedisMongoDB的重要原因:

  • key 不能超过 250 个字节;
  • value 不能超过 1M 字节;
  • key 的最大失效时间是 30 天;
  • 只支持 K-V 结构,不提供持久化和主从同步功能。

Redis

先简单说一下 Redis 的特点,方便和 MC 比较。

  • 与 MC 不同的是,Redis 采用单线程模式处理请求。这样做的原因有 2 个:一个是因为采用了非阻塞的异步事件处理机制;另一个是缓存数据都是内存操作 IO 时间不会太长,单线程可以避免线程上下文切换产生的代价。
  • Redis 支持持久化,所以 Redis 不仅仅可以用作缓存,也可以用作 NoSQL 数据库。
  • 相比 MC,Redis 还有一个非常大的优势,就是除了 K-V 之外,还支持多种数据格式,例如 list、set、sorted set、hash 等。
  • Redis 提供主从同步机制,以及 Cluster 集群部署能力,能够提供高可用服务。

 

 

 

Redis基础:(该帖子属于下面这个链接的第一篇帖子)

https://juejin.im/post/5db66ed9e51d452a2f15d833

Redis系列:

https://zhuanlan.zhihu.com/p/91539644

Redis双写一致性,并发竞争,线程模型:

https://zhuanlan.zhihu.com/p/91196300

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值