之前对Redis的学习比较笼统,接下来一段时间会跟BiliBili大学系统的过一遍,以下笔记大多来自尚硅谷提供的Redis笔记。

Redis的几个应用场景

减少cpu的压力

在需要多台机器实现负载均衡的场景下,可以进行以下应用
image.png

缓解io读取的压力

redis是存储在内存中的,减少了io操作
image.png

Redis的几个基本数据类型

几个关于key的操作

image.png

1.String

基本命令

image.png
image.png
image.png

底层数据结构

image.png

2.List

基本命令

image.png

底层数据结构

image.png

3.Set

基本命令

image.png

数据结构

image.png

4.Hash

为什么要用Hash结构

分析一下用其他方式存储的缺点。
image.png

基本命令

hset 集合中的 键赋值
hget 集合取出 value
hmset ... 批量设置hash的值
hexists查看哈希表 key 中,给定域 field 是否存在。
hkeys 列出该hash集合的所有field
hvals 列出该hash集合的所有value
hincrby 为哈希表 key 中的域 field 的值加上增量 1 -1
hsetnx 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在

数据结构

Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。

5.ZSet

Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了 。
因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。
访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。

基本命令

image.png

数据结构

zset底层使用了两个数据结构
(1)hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。
跳表
跳表可以理解为用空间来换时间,是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。
image.png
通过这个图感觉更好理解一点
image.png

Redis为什么用跳表不用红黑树

为什么Redis选择使用跳表而不是红黑树来实现有序集合?

首先,我们来分析下Redis的有序集合支持的操作:
1)插入元素
2)删除元素
3)查找元素
4)有序输出所有元素
5)查找区间内所有元素
其中,前4项红黑树都可以完成,且时间复杂度与跳表一致。
但是,最后一项,红黑树的效率就没有跳表高了。
在跳表中,要查找区间的元素,我们只要定位到两个区间端点在最低层级的位置,然后按顺序遍历元素就可以了,非常高效。
而红黑树只能定位到端点后,再从首位置开始每次都要查找后继节点,相对来说是比较耗时的。
此外,跳表实现起来很容易且易读,红黑树实现起来相对困难,所以Redis选择使用跳表来实现有序集合。

跳表的性质

(1)跳表是可以实现二分查找的有序链表;

(2)每个元素插入时随机生成它的level;

(3)最低层包含所有的元素;

(4)如果一个元素出现在level(x),那么它肯定出现在x以下的level中;

(5)每个索引节点包含两个指针,一个向下,一个向右;

(6)跳表查询、插入、删除的时间复杂度为O(log n),与平衡二叉树接近;(空间复杂度为O(n))

6.BitMap

基本命令

  • setbit设置Bitmaps中某个偏移量的值(0或1)
  • getbit获取Bitmaps中某个偏移量的值
  • bitcount[start end] 统计字符串从start字节到end字节比特值为1的数量
  • bitop and(or/not/xor) [key…]

数据结构

Redis提供了Bitmaps这个“数据类型”可以实现对位的操作:
(1)Bitmaps本身不是一种数据类型, 实际上它就是字符串(key-value) , 但是它可以对字符串的位进行操作。
(2)Bitmaps单独提供了一套命令, 所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标在Bitmaps中叫做偏移量。
image.png

BitMap与Set比较

以下所说的访问量大小均是相对于总共注册用户来讲的
当每天访问用户量大时,使用BtiMap更好,能够有效的节省空间
当每天访问用户量较小时,使用Set更能够节约空间

7.HyperLogLog

用来统计基数,和Set的区别是不存储具体的数据本身,只用来统计个数

HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

基本命令

pfadd
pfcount ... 计算HLL的近似基数 该命令也可以计算多个hll
pfmerge a b c(后面跟三个参数,b、c合并之后生成a)

Geospatial

用来进行经纬度操作(感觉挺实用的)

Redis 3.2 中增加了对GEO类型的支持。GEO,Geographic,地理信息的缩写。该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。

基本命令

  • geoadd< longitude> [longitude latitude member...] 添加地理位置(经度,纬度,名称)
  • geopos [member...] 获得指定地区的坐标值
  • geodist [m|km|ft|mi ] 获取两个位置之间的直线距离
  • georadius< longitude>radius m|km|ft|mi 以给定的经纬度为中心,找出某一半径内的元素

Redis的事务

Redis的事务实际上相当于是一种乐观锁。
涉及到watch,multi,exec命令

Redis事务的特点

image.png

持久化操作

RDB

每隔一段时间,会备份当前的数据生成一个RDB文件(dump.rdb)

RDB文件生成的过程

先fork一个子进程,之后的io操作都在这个子进程上进行。子进程先将此刻的数据都写入一个临时文件,全部写入完毕后,再用临时文件替换原来的rdb文件

RDB的优缺点

优点:磁盘占用空间较小,资源相对恢复快;缺点容易丢失一部分数据(最后一次数据容易丢失),且rdb持久化的过程中要考虑二倍膨胀的问题。

AOF

没进行一次数据修改(读不算),就在aof文件后计入相应操作,下次启动后将aof文件中记录的操作重新进行一遍来恢复数据

aof的同步频率

image.png

aof的重写

redis4.0版本后的重写,是指上就是把rdb 的快照,以二级制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作。

随着数据的不断更改,aof会越来越大,此时就需要进行aof的重写。这是会fork一个子进程在缓冲区中进行重写,新发生的更改操作会同时写入缓冲区和原aof文件,写入完成后,将新生成的aof文件替换原来的

优缺点

优点不容易丢失数据,缺点占用空间大且,发生意外后数据恢复较慢

主从复制

  1. 刚开始从服务器连接到主服务器后,会发送同步请求
  2. 主服务器接收到同步请求后会进行rdf持久化,并将这个rdf文件发送给从服务器
  3. 在之后主服务器数据更新后,都会主动和从服务器进行同步

能干啥

读写分离;容灾快速恢复
image.png

哨兵模式

反客为主的自动版
反客为主即 slaveof no one
当主机挂掉之后,选举一个从机作为主,当原来的主恢复后,这个主机会作为从机
下面这个图可能会更清楚一点
image.png

新建哨兵模式的配置文件

sentinel monitor mymaster 127.0.0.1 6379 1
其中mymaster为监控对象起的服务器名称, 1 为至少有多少个哨兵同意迁移的数量。

启动哨兵

redis-sentinel /myredis/sentinel.conf
linux vim的替换操作:%s

Q.E.D.