缓存层redis总结

缓存层(redis)

数据缓存层的原理

数据缓存层实际上就是对一个巨大的存在于内存中的DataSet进行管理,其原理如下:

(1)数据缓存层维护一个大DataSet,这个DataSet以static存在于应用程序中,这是缓存数据集。

(2)客户端发起请求,数据查询请求发送到数据缓存层。

(3)数据缓存层查询缓存起来的数据查询条件,查找该查询条件是否被使用过。

(4)如果该查询条件以前使用过,则不从数据库查询数据,只从缓存数据集中查询。

(5)如果该查询条件以前没有用过 ,则调用数据访问层从数据库中查询数据,并将查询数据合并到缓存数据集中,同时缓存该查询条件。

(6)更新数据时,将要更新的数据更新到数据库中,同时更新缓存数据集中的数据。

(7)在查询或更新数据时,都在缓存数据集相应数据表的扩展属性中记录当前访问时间。

(8)每隔一段时间对缓存数据集进行清理,当其中某条数据行超过一定时间(可以在配置文件中进行配置)没有访问,则将该表释放。

定义

redis是一个key-value存储系统。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。

为什么那么快:

+ Redis嘛,就是一种并发很强的跑在内存上的NoSql数据库,支持键到五种数据类型的映射。
  • 首先,采用了多路复用io阻塞机制 然后,数据结构简单,操作节省时间 最后,运行在内存中,自然速度快

 

redis的五大数据类型:

String 整数,浮点数或者字符串 Set 集合 Zset 有序集合 Hash 散列表 List 列表

redis持久化机制和原理

  • RDB 持久化 将某个时间点的所有数据都存放到硬盘上。 可以将快照复制到其它服务器从而创建具有相同数据的服务器副本。 如果系统发生故障,将会丢失最后一次创建快照之后的数据。 如果数据量很大,保存快照的时间会很长。 AOF 持久化 将写命令添加到 AOF 文件(Append Only File)的末尾。 使用 AOF 持久化需要设置同步选项,从而确保写命令同步到磁盘文件上的时机。这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。有以下同步选项: 选项同步频率always每个写命令都同步everysec每秒同步一次no让操作系统来决定何时同步

原理:

  • 客户端向服务端发送写操作(数据在客户端的内存中)。

  • 数据库服务端接收到写请求的数据(数据在服务端的内存中)。

  • 服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。

  • 操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。

  • 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。

哨兵模式:

sentinel负责持续监控主节点的健康,当主节挂掉时,自动选择一个最优的从节点切换成主节点,当主节点发生故障时,sentinel会将最新的主节点地址告诉客户端,可以实现无需重启自动切换redis。Sentinel支持集群。

雪崩,击穿,穿透:

雪崩:缓存层承载着大量请求,有效的保护了存储层,存储层的调用量会暴增,造成存储层会挂掉的情况。

穿透:缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,接着查询数据库也无法查询出结果,但是这将会导致每个查询都会去请求数据库,造成缓存穿透。

击穿:缓存击穿,就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当key失效时,大量的请求就会击穿数据库

redis集群是怎么做的:

* codis集群 codis是redis集群解决方案之一,codis是GO语言开发的代理中间件

  • 官方cluster方案

  • twemproxy代理方案

  • 哨兵模式

  • codis

  • 客户端分片

redis事物:

redis事物是可以一次执行多个命令,本质是一组命令的集合。2. 一个事务中的所有命令都会序列化,按顺序执行就不会被其他命令插入。

redis实现悲观锁,乐观苏,分布式锁:

悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。

分布式锁实现原理

在进程请求执行操作前进行判断,加锁是否成功,加锁成功允许执行下步操作;

如果不成功,则判断锁的值(时间戳)是否大于当前时间,如果大于当前时间,则获取锁失败不允许执行下步操作;

如果锁的值(时间戳)小于当前时间,并且GETSET命令获取到的锁的旧值依然小于当前时间,则获取锁成功允许执行下步操作;

如果锁的值(时间戳)小于当前时间,并且GETSET命令获取到的锁的旧值大于当前时间,则获取锁失败不允许执行下步操作;

分布式锁的作用:

redis写入时不带锁定功能,为防止多个进程同时进行一个操作,出现意想不到的结果,so...对缓存进行插入更新操作时自定义加锁功能。

数据类型的结构:

1.字符串类型:可以存储任何形式的字符串,也包括二进制流数据。string类型默认支持三种数据格式:字符串,整数,浮点。

2.列表:可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素或者获得列表的某一个片段。时间复杂度为O(1)。

3.hash类型:把整体看作一个对象,每个field-value相当于对象的属性和属性值。是个典型的字典结构,在value里面不能再嵌套其他的数据类型的格式。

使用场景:hash的存储方式类似于关系型数据库,可以存储一些对象形式的信息。

4.集合类型(set):集合类型中,每个元素都是不同的,也就是不能有重复数据,同时集合类型中的数据是无序的。集合类型和列表类型的最大的区别是有序性和唯一性 集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在。由于集合类型在redis内部是使用的值 为空的散列表,所以这些操作的时间复杂度都是O(1).

5.有序集合 (sorted-set,(zset)):有序集合类型为集合中的每个元素都关联了一个分数,能获得分数最高(或最低)的前N个元素、获得指定分数范围内的元 素等与分数有关的操作。虽然集合中每个元素都是不同的,但是他们的分数却可以相同 。

 

哈希冲突怎么办:

1.开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列) 2.再哈希法 3.链地址法(Java hashmap就是这么做的) 4.建立一个公共溢出区