1.redis的出现。
最初所有的数据文件都存放在磁盘,每次读取都需要进行全量的IO查询,速度极慢。后来有了数据库,将数据有结构有约束的存放起来,包括索引,也是一种数据结构,主要是映射数据地址(mysql选用B+树)。但是内存的读写速度远远大于磁盘的读写。所以redis,memcached等内存数据库出现了。那么为什么redis选用k - v的数据结构(个人理解:因为数据库数据之间是存在sql约束的,我们的redis并不能将所有的数据都存放在内存中,只存放热点数据。所以用sql形式的数据可能会造成sql约束依赖失败,最终选择了K - V)这种结构。
redis是一个单线程的worker,操作都是串行话的,不存在线程安全问题。但是在redis 6.X之后,提供了IO threads的IO多线程来专门处理IO的读写操作。但是worker线程还是一个。
一个client的一个connection里发送的指令是有顺序的。
2.redis和memcache的区别。
1.redis和memcache都是k-v的内存型数据库,但是redis的value具有更多的数据结构(string、list、hash、set、zset)。
2.redis可以将数据持久化到磁盘,开机可以恢复加载使用。memcache重启数据丢失。
3.redis可以用作MQ。memcache可以缓存图片,视频。
4.redis支持主从数据备份。
5.redis可以通过aof来进行灾难恢复。
3.redis value的5个数据结构
String:字符串、数值、二进制。redis是二进制安全的(单字符字节数值)(redis. hbase. kafka. zookeeper都是二进制安全的)二进制(bitmap,超过8位自动扩容,场景:布隆过滤器,统计分析)。数值:(场景:秒杀限流)
list:双向链表。同向指令:栈;异向指令:队列;Lindex:数组;Ltrim:评论,裁剪数据
hash:场景:详情页,,聚合(不同数据库的数据)
set:集合(去重,无序)。指令:SRANDMEMBER k1 (正数:无重复。负数:有重复)。场景:抽奖,随机事件,验证码。redis中使用set成本很大,可以独立到一个redis实例进行处理。
zset:有序集合(去重,有序)。每个元素有一个score和rank。场景:排行榜、热搜、翻页。zset是动态维护顺序的。
zset的底层数据结构和实现:通过hashmap和skiplist跳跃表来实现。1.将元素放到合适的位置。2.随机进行造层操作。遍历的时候从最高层往下层遍历。提升查询效率
redis的使用场景
缓存、统计bitmap、秒杀限流(数值计算)、数据迁出(无状态,队列,栈,数组,hash,java数据迁出,spring单例)、聚合数据详情页(hash)、抽奖,随机事件、推荐系统、可能认识的人(集合)、排行榜,热搜(zset)
Redis 分布式
分布式的CAP定理。(Consistency 一致性性)、(Availability 可用性)、(Parition tolerance 分区容错)。这三者不能共存,但是一般来说P是不可避免的,可认为是一直存在的,所以A和C是不能共存的。
redis 持久化。
1.rbd。快照(默认方式),回复速度快,但是会有数据丢失,数据不一致。
2.aof。日志,三个级别:1.每操作,完整性,一致性提高,性能下降。2.每秒钟,OS缓冲刷写,一个buffer。默认方式。3.程序调用。
怎么使用持久化。早些版本时候,rbd和aof是不能通用的。默认是rbd的方式.新版本,两者可以共用,在rdb的后面追加日志文件。
redis可用性,生成系统中,2个问题:
1.压力。分片集群,代理集群。压力问题可以采用Y向(纵向扩展),将整个系统的业务进行划分,划分为多个模块,每个服务执行不同的业务模块。这种方式之后发现如果一个服务进行划分之后仍然特别大,这个时候就需要考虑负载均衡,数据分治,分片。Z向扩展,可以采用hash算法来进行负载均衡,但是如果后期数据量增加的特别多,不便于维护。所以redis提供了一个概念——槽位(预分区)。进行物理节点绑定,后期如果数据增大,会自动的进行扩展。
2.单点故障。主从主备。单点故障可以采用X向(横向)扩展,进行主从备份操作。保证单个服务挂掉之后能有别的服务可以使用。这之间涉及到数据的同步问题,一致性问题(CAP中的C)。
一致性,3种:
强一致性:主服务将需要同步的数据发送给从服务之后,等待从服务返回成功信息之后才向客户端返回响应。这样A,可用性就降低。如果从服务和主服务之间通信断掉了,那么会造成永远也不向客户端返回响应。
弱一致性:主服务向从服务发送数据之后不等待从服务返回直接向客户端返回响应。这样保证服务的可用性(A),但是无法保证数据的一致性(C)。
最终一致性:redis没有提供最终一致性。在主服务和从服务之间增加一个可靠的黑盒媒介(如HDFS中的JournalNode)。主服务将数据发送到这个媒介中,然后向客户端返回响应,从服务可以从这个媒介中拉取数据,保证数据的最终一致性。
分布式锁
redis做分布式锁和zookeeper做分布式锁。redis无主模型,在抢锁的时候,如果有一个抢到了过半的锁那么久获得锁,如果没有就释放锁,通过主动轮询的方式循环。而zk通过注册回调,事件机制来向客户端返回锁的状态信息。抢锁的时候,所有的请求都会交给zk的leader来处理,然后再发送到follower。更推荐使用zk,不推荐使用redis来实现分布式锁