转载
最近更新: 2021/08/30 23:16

数据库基础 - Redis

【狂神说Java】Redis最新超详细版教程通俗易懂

Remote Dictionary Server 远程字典服务,是一个开源的、支持网络、可基于内存也可以持久化的日志型、Key-Value数据库。可以用作数据库、缓存和消息中间件(消息队列)。

redis为了保证效率,数据都是缓存在内存中。效率高,可作为其他数据库,如MySQL的缓存。

持久化:redis会周期性的把更新的数据写入磁盘(RDB),或者把修改操作写入追加的记录文件(AOF),并且在此基础上实现了master-slave(主从)同步。

性能

reids是基于内存操作的,cpu不是redis的性能瓶颈,而是内存和带宽。所以redis是单线程的。

为什么单线程还那么快?

redis所有的数据存储在内存中,不存在I/O阻塞和调度的情况,也就不需要多个线程提高并发,多线程反而会导致CPU调度的额外消耗。

redis使用了I/O多路复用技术,能够使用单线程同时处理多个连接。


数据类型

详见Redis中文官方网站

string字符串

最常用的类型,可以用set, get, append, strlen进行字符串操作。

getrange 截取字符串 setex 创建有寿命的项 setnx 不存在再创建

redis可以识别整型数字,可以进行整型数操作, 如incr命令 +1, decr -1, incrby +n , decrby -n 等。

hash散列

哈希表,结构是 key-<key, value>,即string格式中的value变成了一个哈希表

list列表

底层实现是双向链表,实现各种线性表的操作

set集合

无序的集合,底层实现是哈希表

sorted set(Zset)有序集合

在定义的时候要给每一个记录添加一个score值,用来排序。score值需要是合法的float值。

bitmap位图

位存储,用于高效率存储双状态量。

hyperloglog

用于基数统计,即统计不重复的元素数量,譬如网站的访问人数。

理论上set也能用,但hyperloglog占用内存小。每个 HyperLogLog 键只需要花费 12KB 内存,就可以计算接近 2^64 个不同元素的基数。

因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。也因此 HyperLogLog 会存在少量的误差,约为0.81%。

geospatial 地理位置

用于定位,包括经度、纬度、名称等属性,可以计算地点的距离、指定半径内的其他地点等。经纬度数据是float格式,有效的经度是-180~180,纬度是-85~85。

底层实现是用Zset,可以用Zset命令来操作geo。


事务

一组命令的集合/队列。

  • 一次性:命令会在队列中一次性执行
  • 顺序性:命令是按照顺序执行的
  • 排他性:命令间不会互相干扰

redis的单条命令是原子性的,但是事务不保证原子性

redis事务没有隔离级别

事务异常处理

编译异常:如果事务代码有语法错误,会抛出异常,事务取消

运行时异常:如果事务中存在数据性错误(如访问一个空值),则其他命令正常执行,错误命令抛出异常。所以没有原子性!

乐观锁

redis 用版本号机制实现乐观锁。

在事务之前使用watch语句监视修改值,watch语句获取对应值的版本号。如果事务提交之前有其他线程修改了对应值,则使本事务失败。

失败后如果要再次执行事务,应先用unwatch先解锁再加锁。


持久化

redis是内存数据库,如果不持久化,数据断电即失。

RDB(Redis Database)

指定的时间间隔将内存中的数据快照写入磁盘文件(默认dump.rdb)。恢复时直接将redis目录下的快照文件读入内存。

redis会单独创建一个子进程来进行持久化,会先将数据写入一个临时文件,等到持久化过程结束,再用临时文件代替之前的的数据库快照文件。

过程中主进程无须进行I/O操作,所以RDB效率较高,适合大规模的数据恢复。

缺点是如果最后一次持久化出错,则会出现一段时间的数据丢失,所以适用于数据完整性要求不高的情景。

AOF(Append Only File)

将所有的写操作追加记录在日志文件中,redis启动时会读取日志文件进行数据库重构。

可以控制追加日志文件的频率,如每次操作都追加,或者每隔几秒追加。

显然,效率较低,且日志文件远大于RDB。但是数据完整性好。


redis集群

发布和订阅

redis发布订阅是一种消息通信模式,发布者发送消息,订阅者接收消息。

redis客户端可以订阅任意数量的频道。和kafka类似,但采用的是服务器推送模式。

主节点和从节点

默认情况下,redis每一台服务器都是主节点 master,从节点 slave 需要手动配置。每一个主节点可以有多台从节点。

所有的写操作都由主节点完成,从节点负责从主节点处备份数据,以及处理读操作。在读多写少的情况下,可以实现负载均衡。

配合哨兵模式,可以在主节点宕机之后,选择一个从节点晋升为主节点。如果没有哨兵,则 slave 需要等待 master 恢复

全量复制:slave 会将接收到的数据全部存盘并加载进内存

增量复制:master 将修改命令依次发给 slave,完成同步

每次主节点和从节点进行连接或恢复,都会进行全量复制。

哨兵模式

一般情况下,如果主节点宕机,需要手动配置新的主节点,费时费力,还会造成一段时间服务不可用。哨兵是redis的独立进程,可以检测节点的可用性。如果主节点宕机,则选举出新的主节点。

哨兵通过发送命令,让服务器回应其运行状态,包括 master 和 slave。当哨兵检测到 master 宕机,会通过投票的方式选出一个 slave 成为新的 master ,然后通过发布订阅模式告知其他 slave,修改配置文件,切换 master。

单哨兵的可靠性依旧不够,可以配置多个哨兵,哨兵之间也会进行监控。

过程

  1. 假设 master 宕机,哨兵检测到这个结果,会将其标记为“主观下线”。

  2. 当其他哨兵也检测到宕机,并且数量达到一定值时,哨兵会发起投票。投票的目标写在配置文件中。

  3. 进行故障转移failover操作,切换 master。

  4. 通过发布订阅模式告知其他 slave,称为“客观下线”。

优点:主从配置模式提高可用性,实现负载均衡。自动切换主从,健壮性提高。

缺点:配置复杂,不易扩容

评论区