Redis学习记录

1、Redis概述

1.1、初识NoSQL

概述:NoSQL指"不仅仅是SQL",泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应对超大规模和高并发类型纯动态网站显得力不从心,暴露了很多难以克服的问题。

结构化数据与非结构化数据的区别

①、结构化数据指的是由二维表结构来逻辑表达和实现的数据,严格遵循数据格式与长度规范,也称作为行数据。

②、非结构化数据指的是数据结构不规则或不完整,没有任何预定义的数据模型,不方便用二维逻辑表来表现的数据,例如办公文档(Word)、文本、图片、HTML、各类报表、视频音频等。

1.2、NoSQL的分类

1.2.1、KV型NoSQL

概述:KV型NoSql顾名思义就是以键值对形式存储的非关系型数据库,是最简单且最容易理解的NoSql,以Redis为代表。

特点:①、数据基于内存,读写效率高;

②、KV型数据,时间复杂度为O(1),查询速度快。

注意:KV型NoSql最大的优点就是高性能,利用Redis自带的BenchMark做基准测试,TPS可达到10万的级别,性能非常强劲。

1.2.2、列式NoSQL

概述:列式NoSql,大数据时代最具代表性的技术之一,常用于存储实时产生的数据(例如打车软件的定位信息),以HBase为代表。

注意:①、查询时只有指定的列会被读取,不会读取所有列;

②、列数据被组织到一起,一次磁盘IO可以将一列数据一次性读取到内存中。

1.2.3、文档型NoSQL

概述:文档型NoSql指的是将半结构化数据存储为文档的一种NoSql,文档型NoSql通常以JSON或者XML格式存储数据,常用于存储文章,博客等内容较多的信息,以MongoDB为代表。

注意:关系型数据库是按部就班地每个字段一列存,在MongDB里面就是一个JSON字符串存储。

1.2.4、搜索型NoSQL

概述:传统关系型数据库主要通过索引来实现快速查询,但是在全文搜索的场景下,索引是无能为力的,like查询一是无法满足所有模糊匹配需求,二是使用限制太大且使用不当容易造成慢查询,搜索型NoSql的诞生正是为了解决关系型数据库全文搜索能力较弱的问题,以ElasticSearch作为代表产品。

1.3、关系型与非关系型数据库的优缺点

1.3.1、关系型数据库

概述:关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织。

优点

①、易于维护,都是使用表结构,格式一致;

②、使用方便,SQL语言通用,可用于复杂查询;

③、支持复杂操作,可用于一个表以及多个表之间非常复杂的查询。

缺点

①、读写性能比较差,尤其是海量数据的高效率读写;

②、固定的表结构,灵活性不强;

1.3.2、非关系型数据库

优点

①、格式灵活,存储数据的格式可以是键值对形式、文档形式、图片形式等等,文档形式、图片形式等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型;

②、读写速度快,nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;

③、扩展性高;

④、成本低,nosql数据库部署简单,基本都是开源软件。

缺点

①、不提供sql支持,学习和使用成本较高;

②、一般都不支持事务处理;

③、数据结构相对复杂,复杂查询方面稍欠。

1.4、初识Redis

概述:Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库。

特点

①、基于内存运行,性能高效;

②、支持分布式,理论上可以无限扩展;

③、Key-Value存储系统;

④、开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。


2、Redis安装与入门

2.1、Linux操作系统下安装Redis

2.1.1、搭建虚拟机

        首先在VMware新建一个虚拟机,用于后期学习Redis(不会搭建虚拟机可以参考我的hadoop2.7小白级环境搭建教程中第一章有关搭建虚拟机的操作或去b站找视频跟做)。

2.1.2、对虚拟机进行网络设置

①、首先打开vmware,找到左上角的编辑-->点击虚拟网络编辑器:

②、点击新弹出窗口中位于右下角的更改设置:

③、切换到Nat模式,然后记录IP所属网段和虚拟机网关:

④、打开虚拟机,通过如下命令更改虚拟机网络配置信息:

vi /etc/sysconfig/network-scripts/ifcfg-ens33

⑤、进入文件后,参考下图进行修改:

⑥、最后通过如下命令重启虚拟机,等待虚拟机重启后ping任意网站查看是否成功,如果成功就说明我们的网络设置成功了:

# 重启虚拟机
reboot

# 登录虚拟机后通过ping命令验证虚拟机的网络设置
ping baidu.com
# 通过Ctrl+C暂停

2.1.3、获取Redis下载链接

        进入Redis的下载目录,找到自己想要下载的redis版本(注意:要找.tar.gz格式的文件),鼠标放在对应版本上,鼠标右键-->左键点击复制链接:

2.1.4、下载并解压文件

        打开虚拟机,通过root用户输入如下命令,表示在根目录下创建一个名为download的目录,然后进入download目录后下载redis压缩包并解压到/usr/local目录下:

# 创建download目录
mkdir download
# 进入download目录
cd download 
# 安装用于下载的wget
yum install wget -y
# 通过wget下载我们前面复制的链接中存在的Redis压缩包
wget https://download.redis.io/releases/redis-7.0.2.tar.gz
# 将Redis压缩包解压到/usr/local目录下
tar -zxvf redis-7.0.2.tar.gz -C /usr/local

2.1.5、下载C语言编译环境

        进入Redis的存放目录/usr/local,通过命令安装C语言编译环境(因为Redis是基于C语言开发,所以需要C语言的编译环境):

# 进入Redis的安装目录
cd /usr/local

# 查看该目录下的文件
ll

# 进入Redis目录
cd redis-7.0.2

# 安装C语言编译环境
yum install -y gcc

2.1.6、编译Redis

        在redis-7.0.2目录下执行make命令,将Redis源代码编译成可执行文件。

# 确认自己在redis-7.0.2目录下
pwd

# 执行make命令
make

2.1.7、安装Redis

        在redis-7.0.2目录下执行该命令,将编译后的数据安装到预定目录。

make install

        从上图可知,预定目录为/usr/local/redis-7.0.2/src,进入该文件通过ls命令可以发现该目录中有很多文件:

重点文件说明

redis-benchmark:Redis自带的基准性能测试工具

redis-check-aof:对有问题的 AOF 文件进行修复,AOF和RDB文件后面会说明

redis-check-rdb:对有问题的 RDB文件进行修复

redis-sentinel:Redis集群使用

redis-cli:客户端

redis-server:启动服务器

2.1.8、验证Redis

        进入/usr/local/redis-7.0.2/src目录,通过如下命令启动一个单机版Redis

# 本质上是打开了一个可执行文件
./redis-server

运行结果如下:

通过上图可知,Redis的默认端口号为6379,但启动后发现通过./redis-server启动的服务在前台运行,可以考虑修改Redis的核心配置文件redis.config的参数使Redis处于后台运行:

# 进入Redis解压后的目录(/usr/local/redis-7.0.2)
cd ..

# 通过ll命令查看是否有redis.conf文件
ll

编辑文件,将daemonize的值修改为yes:

# 编辑文件
vi redis.conf

# 搜索参数
/daemonize

搜索到daemonize后按i键,然后将no修改为yes,再按ESC键,输入 :wq 后回车即可:

实操一下后台运行redis服务:

前面已经了解到Redis的默认端口号为6379,我们查看一下6379端口的状态就可以指定Redis是否在运行了:

# 首先下载用于查看端口状态的lsof
yum install -y lsof

# 通过lsof查看端口状态
lsof -i:6379

运行结果如下:

有对应的内容就说明该端口在运行中,至此我们的Redis已经安装成功了!

注意:在src目录下除了redis-server文件可以启动外,redis-cli也可以启动redis。


2.2、Redis入门

2.2.1、默认16个数据库

概述:Redis是一个字典结构的存储服务器,一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与关系数据库实例中可以创建多个数据库类似,所以可以将其中的每个字典都理解成一个独立的数据库。

验证:在Redis目录下的redis.conf文件中查询database就能发现默认是16个数据库(下标从0开始,到15结束,共16个数据库)。

# 先进入/usr/local/redis-7.0.2目录
cd /usr/local/redis-7.0.2

# 编辑redis.conf文件
vi redis.conf

# 搜索database关键字(不要按i键)
/database (输完回车即可)

跳转到如下位置:

2.2.2、Redis的线程

概述:Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。由于单线程容易实现,而且CPU不会成为瓶颈,因此Redis顺理成章地采用单线程的方案。

注意:由于Redis采用单线程的方案,所以Redis的高效性不是由于多线程的原因,真正的原因是采用网络IO多路复用技术来保证在多连接的时候,保证系统的高吞吐量。这里 "多路" 指的是多个网络连接,"复用" 指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗),且Redis在内存中操作数据的速度非常快(内存内的操作不会成为这里的性能瓶颈),因此造就了Redis具有很高的吞吐量。

2.2.3、切换数据库

语法

select 下标

实操1:链接Redis,为第一个数据库添加任意数据,然后切换到第二个数据库,看是否能拿到第一个数据库的数据。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 启动redis使其在后台运行
redis-server ../redis.conf

# 打开redis客户端
redis-cli

# (默认进入第一个数据库,小标为0)为数据库添加一个键为k1,值为10的数据
set k1 10

# 获取当前数据库中键为k1的值
get k1

# 切换到第二个数据库(下标为1)
select 1

# 获取当前数据库中键为k1的值
get k1 

# 再次切换到第一个数据库
select 0

# 获取当前数据库中键为k1的值
get k1 

运行结果如下:

2.2.4、清空当前库

语法

FLUSHDB 

实操2:在实操1的基础上清空第一个数据库中的数据并验证是否清空。

# 通过如下命令直接清空当前数据库中所有的内容
flushdb

# 尝试获取前面添加的键位k1的值
get k1

运行结果如下:

2.2.5、删除所有库的数据

语法

FLUSHALL

实操3:为下标为3的库添加任意数据,然后在其他库通过删除所有库的命令删除所有数据库数据,再查看下标为3的数据库数据是否还存在。

# 切换到小标为3的数据库
select 3

# 添加一个键为num,值为123的数据
set num 123

# 获取键位num的值
get num

# 切换到下标为4的数据库
select 4

# 清空所有数据库的数据
flushall

# 切换到小标为3的数据库
select 3

# 再次获取键位num的值
get num

运行结果如下:


3、Redis数据类型

3.1、键相关的语句

3.1.1、keys & scan

概述:keys用于查看当前库中所有的键。

语法

keys 要查找的值/通配符/要查找的值+通配符

Redis中的通配符

*:通配任意多个字符;

?:通配单个字符;

[ ] :通配中括号中的某一个字符。

实操4:为第一个数据库添加任意数据,然后通过key键获取当前数据库中所有以num开头的键。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 启动redis客户端,方便后面操作数据库
redis-cli

#插入多条数据
set num1 1
set num2 2
set abc 3

# 获取所有以num开头的键
keys num*

运行结果如下:

注意:生产环境中已经禁止了采用keys *查询所有键或指定键的操作,当数据量较大时,长时间阻塞redis会导致其他客户端的命令请求一直处于阻塞状态, 更安全的做法是采用scan。

scan语法

redis-cli [-n 数据库下标] --scan [--pattern "指定字符/通配符/指定字符+通配符"]

-n:用于指定要查询的数据库下标,默认为第一个数据库

--pattern:用于指定匹配的字符,默认值是*,指所有数据库

实操5:采用scan的方式获取第一个数据库中所有以num开头的键。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 以scan的方式获取redis第一个数据库中所有以num开头的键
redis-cli -n 0 --scan --pattern "num*"

运行结果如下:

3.1.2、exists

概述:exists用于判断某个键是否存在,返回1表示存在,0不存在。

语法

exists 键名1 [键名2 键名3...]

实操6:查询第一个数据库中是否存在一个名为num1的键。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 启动redis客户端
redis-cli

# 查看第一个数据库中是否存在名为num1的键
exists num1

# 测试exists能否使用通配符
exists num*
exists *

运行结果如下:

总结:通过实操6可知,existis不支持使用通配符。

3.1.3、type

概述:type用于查看当前键所储存的值的类型,返回当前键所储存的值的类型,如string 、list等。

语法

type 键名

实操7:查看第一个数据库中num1存储的值是什么类型。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 启动redis客户端
redis-cli

# 查看num1的类型
type num1

运行结果如下:

3.1.4、del

概述:del用于删除已存在的键,不存在的键会被忽略,删除成功返回1,删除失败返回0。

语法

del 键名1 [键名2 键名3]

实操8:删除第一个数据库中名为abc的键。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 启动redis客户端
redis-cli

# 删除名为abc的键(数据库中存在的键)
del abc

# 删除一个不存在的键
del def

运行结果如下:

3.1.5、expire

概述:expire用于给键对应的值设置过期时间,设置成功返回 1 ,键不存在返回 0。

语法

expire 键名 时间(单位为秒)

实操9:为第一个数据库中键为num2的值设置过期时间为5秒,5秒后再获取该键的值查看是否成功。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 启动redis客户端
redis-cli

# 查看num2的值
get num2

# 为num2的值设置5秒的过期时间
expire num2 5

# (5秒后执行)再次获取num2的值
get num2

运行结果如下:

3.1.6、ttl

概述:ttl以秒为单位返回键的剩余过期时间。

语法

ttl 键名

实操10:将数据库中num1的过期时间设置为20秒,然后间断地获取剩余过期时间。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 启动redis客户端
redis-cli

# 为num1的值设置为1
set num1 1

# 将num1对应的值的失效时间设置为20秒
expire num1 20

# 获取num1的值当前还剩余多少时间失效
ttl num1

运行结果如下:

总结:当指定的键不存在时,返回 -2; 当指定的键存在但没有设置剩余生存时间时,返回 -1 ; 当指定的键存在且设置了过期时间,将以秒为单位返回指定键的剩余生存时间。

3.1.7、persist

概述:persist 用于移除给定键名的过期时间,使得指定的键永不过期。

语法

persist 键名

注意:当过期时间移除成功时,返回 1 ;如果指定的键名不存在或指定的键名没有设置过期时间,返回 0 。

实操11:为num1设置过期时间为20秒,然后通过persist将num1设置为永不过期,再通过ttl获取num1的过期时间。

# 设置num1的值为1
set num1 1

# 为num1键设置过期时间为20秒
expire num1 20

# 将num1设置为永不过期 
persist num1

# 获取num1的过期时间
ttl num1

运行结果如下:


3.2、String

概述:String是Redis最基本的类型,一个键对应一个值。由于String是二进制的,意味着String可以包含任何数据,比如序列化对象或者一张图片,String最多可以放512M的数据。

使用场景:计数器,统计粉丝数,对象缓存存储,分布式锁。

3.2.1、set & get

概述1:Set用于设置指定键的值。如果指定键已经存储了其他值,set 就重写旧值,且无视类型。

概述2:get用于获取指定键的值。如果键不存在或键的值为空就返回 nil 。

语法

set 键名 值

实操12:为数据库中的num1多次设置值,最后再去获取num1的值,查看其值是多少。

# 多次设置num1的值
set num1 1
set num1 2
set num1 3

# 获取num1的值
get num1

运行结果如下:

3.2.2、append

概述:append用于将给定的值追加到指定键原值末尾。

语法

append 键名 追加的值

注意

①、如果键已经存在并且值是一个字符串, append 命令将值追加到键原来的值的末尾。

②、如果键不存在, append 就简单地将 给定键 设为 指定值 ,与语句 set key value 实现的效果一样。

实操13:为数据库中num1追加内容。

# 获取num1的值
get num1

# 为num1追加内容
append num1 45

# 获取num1的值
get num1

运行结果如下:

3.2.3、strlen

概述:strlen用于获取指定键所储存的字符串值的长度,当键储存的不是字符串值时,会返回一个错误。

语法

strlen 键名

实操14:获取数据库中num1对应的值的长度。

# 获取当前num1的值
get num1

# 获取num1字符串的长度
strlen num1

运行结果如下:

3.2.4、setex

概述:setex用于给指定的键设置值及其对应的过期时间。如果键已经存在, setex命令将会替换旧的值,并设置过期时间。

语法

setex 键名 过期时间 值

实操15:为默认数据库添加一个名为num123的键,对应的值随意,要求设置其过期时间为20秒。

# 设置num123的值为123456,其过期时间为20秒
setex num123 20 123456

# 获取num123的值
get num123

# 获取当前的过期时间
ttl num123

# (20秒后--num123过期后执行)再次获取num123的值
get num123

运行结果如下:

3.2.5、setnx

概述:setnx只有在指定的键名不存在时才能设置指定键对应的值。

语法

setnx 键名 值

实操16:通过setnx添加一个已经存在的键和一个不存在的键。

# 通过setnx创建一个已经存在的键
setnx num1 123

# 通过setnx创建一个不存在的键
setnx num5 100

# 分别获取num1和num5的值(验证是否创建成功)
get num1 
get num5

运行结果如下:

3.2.6、getrange

概述:getrange用于获取指定下标(下标从0开始)区间范围内的值,类似与MySQL中的between...and...语句。

语法

getrange 键名 起始下标 结束下标

实操17:创建任意一个键包含较长内容的值,然后通过getrange语句获取该键下标从2到6的内容信息。

# 通过setnx语句创建一个名为var1的键
setnx var1 muxikeqikeepstudy

# 通过getrange语句获取var键中下标从2到6的字符信息
getrange var1 2 6

运行结果如下:

3.2.7、setrange

概述:setrange用于设置指定区间范围内的值。

语法

setrange 键名 替换的起始下标 值

实操18:将默认数据库中的var1的study替换成relax,并尝试在超出原有字符串长度的下标插入任意数据。

# 获取var1的值
get var1

# 获取var1的长度
strlen var1

# 将study的内容替换成relax
setrange var1 12 relax

# 在超出原有字符串长度的下标位置插入数据
setrange var1 25 hello

# 获取修改后的var的值
get var1

运行结果如下:

3.2.8、incr

概述:incr用于将键中储存的数字值加一。

语法

incr 键名

注意

①、如果键不存在,那么键对应的值会先被初始化为 0 ,然后再执行 incr 操作。

②、如果字符串包含除数字以外的字符或是其他类型的数据,将会返回一个错误。

实操19:分别创建一个值为纯数字的字符串和一个值中包含其他字符的键,将两个键分别用incr语句进行值加一的操作。

# 创建一个值为纯数字的键
seten var2 123

# 对新建的键var2做加一操作
incr var2

# 创建一个值中包含其他字符的键
setnx var3 123abc

# 对新建的键var3做加一操作
incr var3

# 获取var4的值(验证var4不存在)
get var4

# 对var4做加一操作
incr var4

运行结果如下:

3.2.9、decr

概述:decr用于将键中储存的数字值减一。

语法

decr 键名

注意

①、当键不存在时,键的值会先被初始化为 0 ,然后再执行 decr 操作。

②、当字符串类型的值不是纯数字时或是其他类型的值,那么将返回一个错误。

实操20:分别对一个值为纯数字,值中包含其他字符和空值用decr语句做减一处理。

# 获取var2的值
get var2

# 对var2做减一处理
decr var2

# 获取var3的值
get var3

# 对var3做减一处理
decr var3

# 获取var5的值
get var5

# 对var5做减一处理
decr var5

运行结果如下:

3.2.10、增加或减少特定数

概述:前面的学习中通过incr和decr实现对数字的增减,为了提高效率,通过如下语法可以将键存储的数字值按照步长进行增减。

语法

incrby/decrby 键名 步长

实操21:通过实操了解incrby和decrby的用法。

# 获取var2的值
get var2

# 通过decrby语句实现对var2减2
decrby var2 2

# 通过incrby语句实现对var2加50的操作
incrby var2 50

运行结果如下:

注意

①、如果指定键不存在,那么指定键的值会先被初始化为 0 ,然后再执行 incrby/decrby 命令。

②、如果字符串类型的值不能表示为数字、或者是其他类型,将返回一个错误。

3.2.11、mset

概述:mset用于同时设置一个或多个键值对。

语法

mset 键名1 值1 键名2 值2 ...

实操22:为默认的Redis数据库同时添加两个键值对。

# 为默认的第一个数据库添加两个键值对
mset niko 123 donk 456

# 查看默认数据库中的所有键
keys *

运行结果如下:

3.2.12、mget

概述:mget用于返回所有指定键的值。

语法

mget 键名1 键名2 ...

实操23:获取默认数据库中var1,var2,var3,var4和var5的值。

mget var1 var2 var3 var4 var5

运行结果如下:

3.2.13、getset

概述:getset将指定键对应的值设为新传入的值,并返回指定键的旧值,简单一句话(先get然后立即set)。

语法

getset 键名 新传入的值

实操24:为默认数据库中的var1的值覆盖为321,并且要得到var1的旧值。

# 将var1的值替换为321,并获取var1的旧值
getset var1 321

# 查看var1的值
get var1

运行结果如下:


3.3、List

概述:List是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。底层是一个双向链表,对两段操作性能极高,但通过索引操作中间的节点性能较差。

使用场景:消息队列,排行榜等。

3.3.1、lpush & rpush

概述:lpush和rpush分别用于从 左边(头部)或 右边(尾部)插入一个或多个值。

语法

lpush/rpush 键名 值1 值2 值3...

实操25:清空第二个数据库中的所有数据,然后通过lpush和rpush方法为var1插入多个值。

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 使redis在后台运行
redis-server ../redis.conf

# 启动redis客户端
redis-cli

# 切换到第二个数据库(下标为1)
select 1

# 清空当前数据库
flushdb

# 获取当前数据库中所有的键(验证是否成功清空)
keys *

# 通过lpush从var1的左侧插入数据
lpush var1 10 20 30 40 50

# 通过rpush从var1的右侧插入数据
rpush var1 101 102 103 104

运行结果如下:

3.3.2、lrange

概述:返回键列表中从起始下标到结束下标之间的元素(包含起始下标和结束下标)。 其中 0 表示列表的第一个元素,-1表示最后一个元素。

语法

lrange 键名 起始下标 结束下标

实操26:获取第二个数据库中键名为var1的值。

# 获取var1中所有的元素
lrange var1 0 -1

运行结果如下:

注意:lrange语句中的起始下标和结束下标都不能省略,若省略就会报错。

3.3.3、lpop & rpop

概述:lpop和rpop分别用于移除并返回第一个值或最后一个值。

语法

lpop/rpop  键名  删除的元素个数(默认为1)

实操27:删除掉第二个数据库中var1的前两个元素和最后一个元素。

# 查看当前var1中的元素
lrange var1 0 -1

# 删除var1中的前两个元素
lpop var1 2

# 删除var1的最后一个元素
rpop var1

# 查看当前var1中的元素
lrange var1 0 -1

运行结果如下:

3.3.4、lindex

概述:lindex用于获取列表指定下标位置的值(从左开始)。

语法

lindex 键名 指定下标

实操28:查看第二个数据库中列表var1中下标为2对应的值是多少。

# 查看当前var1列表的所有元素
lrange var1 0 -1

# 查看var1中下标为2对应的值
lindex var1 2

运行结果如下:

3.3.5、llen

概述:llen用于获取列表长度。

语法

llen 键名

实操29:获取当前第二个数据库中var1列表的长度。

# 查看当前var1列表中所有的元素
lrange var1 0 -1

# 查看当前var1列表中保存的元素个数
llen var1

运行结果如下:

3.3.6、lrem

概述:lrem用于从左边开始删除与指定值相同的指定个数的元素。

语法

lrem 键名 指定个数 指定值

实操30:为第二个数据库创建一个名为var2的列表,并插入包含多个相同内容的字符串,然后通过lrem语句删除指定个数的指定元素。

# 切换到第二个数据库
select 1

# 创建一个名为var2的列表并插入多个元素
lpush var2 12 11 13 12 14 12 15

# 查看当前var2中所有的元素
lrange var2 0 -1

# var2从左到右删除2个值为12的元素
lrem var2 2 12

# 查看当前var2中所有的元素
lrange var2 0 -1

运行结果如下:

3.3.7、linsert

概述:linsert用于在列表中指定值的前面或后面插入一个新值(从左开始)。

语法

linsert 键名 before/after 指定值 新值

实操31:在第二个数据库的var2列表的中值为14的前面插入字符串"muxi",在14的后面插入字符串"keqi"。

# 查看当前var2列表中所有的元素
lrange var2 0 -1

# 在var2的(从左到右)第一个值为14的前面插入字符串"muxi"
linsert var2 before 14 muxi

# 在var2的(从左到右)第一个值为14的后面插入字符串"keqi"
linsert var2 after 14 keqi

# 查看当前var2中所有的元素
lrange var2 0 -1

运行结果如下:

3.3.8、lset

概述:lset用于将指定索引的值设置为指定的新值(也可以说是根据下标修改值)。

语法

lset 键名 指定索引 指定值

实操32:通过lset将var2列表中第一个元素改为donk。

# 将var2的第一个元素(下标为0)赋值为donk
lset var2 0 donk

# 查看当前var2的所有元素
lrange var2 0 -1

运行结果如下:


3.4、Set

概述

①、与List类似拥有列表功能,但Set会自动排除重复值,当需要存储一个列表数据,又不希望出现重复数据时,Set是一个很好的选择。

②、Set是String类型的无序集合,它底层其实是一个值为null的hash表,所以添加、删除、查找的时间复杂度都是O(1)。

使用场景:黑白名单,随机展示,好友,关注列表,粉丝列表,可能感兴趣的人...

3.4.1、sadd

概述:sadd用于将一个或多个元素添加到集合中,已经存在的元素将被忽略。

语法

sadd 键名(或称集合名) 值1 值2 ...

实操33:清空第三个数据库中所有的键值对,然后通过sadd创建一个名为var1的集合并插入多个拥有重复值的数据。

# 切换到第三个数据库
select 2

# 清空当前数据库
flushdb

# 查看当前数据库中所有的键
keys *

# 通过sadd创建一个名为var1的集合并插入多个元素
sadd var1 1 2 3 4 1 2 4 5 6

运行结果如下:

3.4.2、smembers

概述:smembers用于取出指定集合中所有元素。

语法

smembers 键名(或称集合名)

实操34:取出第三个数据库中var1集合的所有数据。

smembers var1

运行结果如下:

3.4.3、sismember

概述:sismember用于判断指定集合中是否含有指定值的元素,如有返回1,否则返回0。

语法

sismember 键名(或称集合名) 指定值

实操35:通过sismember验证第三个数据库中var1集合中是否存在如下元素:5,"muxi"。

# 获取var1集合中所有的元素(辅助理解下面的程序)
smembers var1

# 判断var1集合中是否存在5
sismember var1 5

# 判断var1集合中是否存在muxi
sismember var1 muxi

运行结果如下:

3.4.4、scard

概述:scard用于返回指定集合中元素的个数。

语法

scard 键名(或称集合名)

实操36:通过scard获取第三个数据库中var1集合中元素的个数。

# 获取var1中所有的元素
smembers var1

# 通过scan获取var1的元素个数
scard var1

运行结果如下:

3.4.5、srem

概述:srem用于删除集合中的一个或多个指定的元素,不存在的元素会被忽略。

语法

srem 键名(或称集合名) 值1 值2...

实操37:删除第三个数据库中var1集合中值为5,6,7的元素。

# 查看var1集合中所有的元素
smembers var1

# 删除var1集合中值为5,6,7的元素
srem var1 5 6 7

# 再次查看var1集合中所有的元素
smembers var1

运行结果如下:

3.4.6、spop

概述:spop用于随机删除集合中一个元素并返回该元素。

语法

spop 键名(或称集合名) [指定删除的个数(默认为1)]

实操38:利用spop删除第三个数据库中var1的任意两个元素。

# 查看var1集合中所有的元素
smembers var1

# 删除var1中任意两个元素
spop var1 2

# 再次查看var1集合中所有的元素
smembers var1

运行结果如下:

3.4.7、srandmember

概述:srandmember用于随机取出集合中指定个数的元素,但不会删除元素。

语法

srandmember 键名(或称集合名) 指定的个数

实操39:为第三个数据库中var1集合添加任意个元素,然后通过srandmember随机取出3个元素。

# 为var1集合添加任意个元素
sadd var1 donk niko shiro zywoo muxi

# 查看var1集合当前的所有元素
smembers var1

# 通过srandmember获取var1中任意3个元素
srandmember var1 3

# 再次查看var1集合当前的所有元素(验证srandmember不会删除元素)
smembers var1

运行结果如下:

3.4.8、smove

概述:smove用于将集合1中指定的元素移动到集合2中。

语法

smove 集合1 集合2 指定的元素(或称为指定的值)

实操40:在第三个数据库中新建一个名为var2的集合,并将var1集合中的值"donk"移动到var2中。

# 创建一个名为var2的集合并插入任意一个元素
sadd var2 123

# 将var1集合中的值"donk"移动到var2集合中
smove var1 var2 donk

# 查看var1集合中当前所有的元素
smembers var1

# 查看var2集合中当前所有的元素
smembers var2

运行结果如下:

3.4.9、sinter

概述:sinter用于返回两个集合的交集元素。

语法

sinter 集合1 集合2

实操41:在第三个数据库中创建名为var3和var4的集合并插入任意多个数据,然后利用sinter获取var3和var4两个集合的交集数据。

# 创建一个名为var3的集合并插入任意数据
sadd var3 1 2 3 4 5 a b c

# 创建一个名为var4的集合并插入任意数据
sadd var4 abc d 1 2 3

# 获取var3和var4的交集
sinter var3 var4

运行结果如下:

3.4.10、sunion

概述:sunion用于返回两个集合的并集元素。

语法

sunion 集合1 集合2

实操42:获取第三个数据库中var3和var4的并集数据。

# 获取var3和var4的并集元素
sunion var3 var4

运行结果如下:

3.4.11、sdiff

概述:sdiff用于返回两个集合的差集元素(即集合1中存在的元素但集合2中不存的元素)

语法

sdiff 集合1 集合2

实操43:获取第三个数据库中var3和var4的差集元素。

# 查看var3集合中所有的元素
smembers var3

# 查看var4中所有的元素
smembers var4

# 获取var3与var4的差集
sdiff var3 var4

运行结果如下:


3.5、Hash

概述:Hash是一个键值对的集合。Hash 是一个 String 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象(hash类型可以理解为整体上还是键值对的形式存储数据,只是值的结构也是以键值对的形式存储数据)。

# hash表结构
键名 字段1 值1 [字段2 值2 ...]

Hash存储结构

①、如果字段数量较少,存储结构优化为类数组结构;

②、如果字段数量较多,存储结构使用HashMap结构。

使用场景:购物车,存储对象。

3.5.1、hset

概述:hset用于给hash表指定键名中的字段赋值。

语法

hset 键名 字段 值

实操44:清空第四个数据库中所有的数据,并利用hset为键名为student的hash表设置多个字段及其对应的值。

# 切换到第四个数据库
select 3

# 清空当前数据库中所有的数据
flushdb

# 获取当前数据库中所有的键
keys *

# 为键名为student的集合设置hash值
hset student name muxikeqi
hset student age 18

运行结果如下:

注意

①、如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。

②、如果字段已经存在于哈希表中,旧值将被重写。

3.5.2、hget

概述:hget用于从hash表指定键名中取出指定字段的值。

语法

hget 键名 指定的字段名

实操45:获取第四个数据库中hash表键名为student,字段为name的值。

hget student name

运行结果如下:

3.5.3、hmset

概述:hmset用于批量设置hash表指定键中的字段及其对应的值。

语法

hmset 键名 字段1 值1 字段2 值2 ...

实操46:为第四个数据库添加一个键名为player的hash表,并插入多个字段及其对应的值。

hmset player name donk damage 120 time 5999

运行结果如下:

3.5.4、hexistis

概述:hexistis用于判断hash表指定键中是否存在指定的字段。

语法

hexists 键名 字段名

实操47:利用hexistis判断第四个数据库中键名为player的hash表是否存在name,age和time字段。

hexists player name
hexists player age
hexists player time

运行结果如下:

3.5.5、hkeys

概述:hkeys用于获取hash表中指定键中所有的字段。

语法

hkeys 键名

实操48:查看第四个数据库中键名为player的hash表中包含的所有字段。

hkeys player

运行结果如下:

3.5.6、hvals

概述:hvals用于获取hash表中指定键包含的所有的值。

语法

hvals 键名

实操49:获取第四个数据库中名为player的键中储存的所有的值。

hvals player

运行结果如下:

3.5.7、hincrby

概述:hincrby用于为哈希表指定键中的指定字段的值加上指定数量的值。

语法

hincrby 键名 字段 指定数量

实操50:将第四个数据库中hash表键名为player中的time字段加10。

# 首先获取player键中当前time的值
hget player time

# 对player键中time字段加10(这里是题目要求)
hincrby player time 10

# 再次获取player键中当前time的值
hget player time

运行结果如下:

注意

①、hincrby的指定数量也可以为负数,相当于对指定字段进行减法操作。

②、如果哈希表的键名不存在,将创建一个新的哈希表并执行 hincrby 命令。

③、如果指定的字段不存在,那么在执行命令前,将会创建一个该字段,并且该字段的值被初始化为 0 。

④、对一个储存字符串值的字段执行 hincrby 命令将造成一个错误。

3.5.8、hdel

概述:hdel用于删除哈希表指定键中的一个或多个指定字段,不存在的字段将被忽略。

语法

hdel 键名 字段1 字段2 ...

实操51:删除第四个数据库中hash表中键名为player中的name字段和age字段。

# 查看键名为player的hash表中所有的字段
hkeys player

# 删除键名为player的hash表中字段为name和age的字段
hdel player name age

# 再次查看键名为player的hash表中所有的字段
hkeys player

运行结果如下:

3.5.9、hsetnx

概述:hsetnx用于给哈希表中指定键不存在的的字段赋值 。

语法

hsetnx 键名 字段 值

实操52:为第四个数据库中hash表键名为player的name和time字段赋任意值,要求如下:如果该字段存在值就不赋值,如果该字段不存在值就赋值。

hsetnx player name donk

hsetnx player time 2000

运行结果如下:

注意

①、如果哈希表不存在,一个新的哈希表被创建并进行 hsetnx 操作。

②、如果字段已经存在于哈希表中,操作无效。

③、如果hash表指定的键名不存在,一个新哈希表被创建并执行 hsetnx 命令。


3.6、Zset

概述:Zset与Set非常相似,是一个没有重复元素(value)的String集合。不同之处是Zset的每个元素都关联了一个分数(score),这个分数被用来按照从低分到高分的方式排序集合中的元素。集合的元素(value)是唯一的,但分数(score)可以重复。

注意:因为元素(value)是有序的,所以可以根据分数(score)或者次序(position)来获取一个范围内的元素。

使用场景:延时队列(例如多少时间之内未支付则订单失效),排行榜,限流。

3.6.1、zadd

概述:zadd用于将一个或多个元素(value)及分数(score)加入到有序集的指定键名中。

语法

zadd 键名 score1 value1 score2 value2……

实操53:清空第五个数据库中所有的数据,并在该数据库中创建一个键名为student的有序集合。

# 切换到第五个数据库
select 4

# 清空当前数据库
flushdb

# 创建一个键名为student的有序集合并插入多条数据
zadd student 95 donk 87 niko 88 shiro 85 magixx 90 muxikeqi

运行结果如下:

注意

①、如果某个元素已经是有序集的元素,那么更新这个元素的分数值,并通过重新插入这个元素,来保证该元素在正确的位置上。

②、分数值可以是整数值或双精度浮点数。

③、如果有序集合 key 不存在,则创建一个空的有序集并执行 zadd 操作。

3.6.2、zrange

概述:zrange用于返回指定键集合中的起始下标到结束下标之间的元素(包含起始下标和结束下标)。

语法

zrange 键名 起始下标 结束下标 [withscores]  # 如果要显示score的信息就要加上withscores语句

实操54:获取第五个数据库中名为student的有序集合中所有的元素(value)及其分数(score)。

zrange student 0 -1 withscores

运行结果如下:

注意

①、元素的位置按分数值递增(从小到大)来排序。 其中 0 表示列表的第一个元素,-1表示最后一个元素。

②、withscores是可选参数,表示是否返回分数。

3.6.3、zrangescore

概述:zrangescore用于返回指定键集合中的指定最小分数和指定最大分数之间的元素(包含指定最小分数和指定最大分数 )。其中元素的位置按分数值递增(从小到大)来排序。

语法

zrangebyscore 键名 指定的最小分数 指定的最大分数 [withscores]

实操55:获取第五个数据库中student键集合中分数为80到90之间的所有分数(score)和元素(value)

zrangebyscore student 80 90 withscores

运行结果如下:

3.6.4、zincrby

概述:zincrby用于为指定键中指定元素(value)的分数(score)加上指定值(increment)。

语法

zincrby 键名 指定值(increme) 元素(value)

实操56:为第五个数据库中student键集合中magixx字段的分数加5。

zincrby student 5 magixx

运行结果如下:

3.6.5、zrem

概述:zrem用于删除指定键集合下的元素(value)及其对应的分数(score)。

语法

zrem 键名 元素(value) 

实操57:删除第五个数据库中student有序集合中的niko元素。

# 删除student集合中值为niko的元素
zrem student niko

# 查看student集合中所有的元素
zrange student 0 -1

运行结果如下:

3.6.6、zcount

概述:zcount用于统计该集合从指定的最小分数到指定的最大分数区间中元素的个数。

语法

 zcount 键名 指定的最小分数 指定的最大分数

实操58:统计第五个数据库中student有序集合中分数在90-100区间元素的个数。

# 统计student有序集合中分数在90-100之间元素的个数
zcount student 90 100

# 获取student有序集合中所有的元素和分数
zrange student 0 -1 withscores

运行结果如下:

3.6.7、zrank

概述:zrank用于返回元素(value)在集合中的排名(从低到高进行排名),排名从0开始。

语法

zrank 键名 元素(value)

实操59:查看第五个数据库中student有序集合中muxikeqi的排名。

# 查看student集合中所有的元素及其分数
zrange student 0 -1 withscore

# 获取muxikeqi在student集合中的排名
zrank student muxikeqi

# (由于muxikeqi和magixx的分数一样,查看两个元素的排名是否会一样)再次获取magixx在student有序集合中的排名
zrank student magixx

运行结果如下:


3.7、Bitmaps

概述:在计算机中,用二进制的位作为存储信息的基本单位,1个字节等于8位,合理地使用位能够有效地提高内存使用率和开发效率,Redis提供了Bitmaps这种"数据结构"可以实现对位的操作,但要注意的是Bitmaps本身不是一种数据结构,实际上它就是一个字符串,只是Bitmaps能对字符串的位进行操作。

使用场景:活跃天数,打卡天数,登录天数,活跃用户,用户是否在线,实现布隆过滤等。

3.7.1、setbit

概述:setbit用于设置Bitmaps中某个偏移量的值。

语法

setbit 键名 偏移量 值

实操60:清空第六个数据库的数据,并利用setbit记录donk在6月前七天的考勤打卡记录。

# 切换到第六个数据库
select 5

# 清空当前数据库的所有数据
flushdb

# donk:6是一个整体(这只是一个名字,和变量一样可以随机),在程序中理解为donk在6月的打卡记录,0表示偏移量,在整个程序中理解为第一天(偏移量即操作的位置,从0开始计数),1表示要设置的值,在程序中我们可以规定1为已打卡,0为未打卡(setbit的值只能为0和1)
setbit donk:6 0 1

# donk在6月的第二天工作
setbit donk:6 1 1

# donk在6月的第三天工作
setbit donk:6 2 1

# donk在6月的第四天工作
setbit donk:6 3 0

# donk在6月的第五天工作
setbit donk:6 4 1

# donk在6月的第六天工作
setbit donk:6 5 0

# donk在6月的第七天工作
setbit donk:6 6 1

运行结果如下:

3.7.2、getbit

概述:getbit用于获取Bitmaps中某个偏移量的值。

语法

getbit 键名 偏移量

实操61:查询donk在6月第7天(存在的数据)和第8天(不存在的数据)是否打卡。

# 获取donk在6月第7天的打卡记录(返回1表示已打卡,返回0表示未打卡)
getbit donk:6 6

# 获取donk在6月第8天的打卡记录(在实操60中我们并没有添加第8天的打卡记录,所以是不存在第8天的打卡记录的)
getbit donk:6 7

运行结果如下:

总结:如果偏移量未设置值,则也返回0。

3.7.3、bitcount

概述:统计字符串被设置为1的bit数量。一般情况下,给定的整个字符串都会被进行统计,可以选择通过额外的起始偏移量和结束偏移量参数,指定字节组范围内进行统计(包括起始偏移量和结束偏移量),0表示第一个元素,-1表示最后一个元素。

语法

bitcount 键名 [起始偏移量 结束偏移量]

实操62:获取donk在6月前7天的打卡天数。

# 由于donk:6键中只储存了前7天的数据,所以可以用-1表示最后一个数据
bitcount donk:6 0 -1

运行结果如下:

3.7.4、bitop

概述:bitop用于将多个bitmaps通过求交集/并集方式合并成一个新的bitmaps。

语法

# and表示交集,or表示并集
bitop and/or 新合并的bitmaps键名 用于合并的bitmaps键名1 用于合并的bitmaps键名2 ...


3.8、Geospatia

概述:Geographic,简称GEO,是地理信息的缩写。该类型就是元素的二维坐标,在地图上就是经纬度。Redis基于该类型,提供了经纬度设置、查询、范围查询、距离查询、经纬度Hash等常见操作。

使用场景:附近的医院,附近的学校,附近的公园。

注意:Redis的储存结构是键值对,GEO中的值包含精度,维度和地理位置相关的名称。

3.8.1、geoadd

概述:geoadd用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。

语法

geoadd 键名 经度 纬度 [与这个地理位置相关联的]名称

实操63:进入第七个数据库,利用GEO将长沙,武汉,北京和成都的地理坐标存放到名为China的键中。

# 切换到第七个数据库
select 6

# 添加长沙的坐标信息到China键中
geoadd China 112.98 28.19 changsha

# 添加武汉的坐标信息到China键中
geoadd China 114.2653 30.6041382 wuhan

# 添加北京的坐标信息到China键中
geoadd China 116.3912757 39.906217 beijing

# 添加成都的坐标信息到China键中
geoadd China 104.0348 30.3936 chengdu

运行结果如下:

3.8.2、geopos

概述:geopos用于从给定的键里返回所有指定名称的经度和纬度,不存在的返回 nil。

语法

geopos 键名 名称1 [名称2 ...]

实操64:获取第七个数据库中GEO里存储的China键中长沙和成都的坐标信息(经度和维度)。

geopos China changsha chengdu

运行结果如下:

3.8.3、geodist

概述:geodist用于返回两个给定位置之间的距离。

语法

# 注意:两个地理名称的坐标信息一定要存放到指定键名中
geodist 键名 地理名称1 地理名称2 [m|km|ft|mi]
# m 表示米,默认单位
# km 表示千米
# ft 表示英尺
# mi 表示英里

实操65:在第七个数据库中,计算China键中成都与长沙相距多少千米。

geodist China changsha chengdu km

运行结果如下:

3.8.4、georadius

概述:georadius用于以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离(radius )的所有位置元素。

语法

georadius 键名 经度 纬度 最大距离(radius) m|km|ft|mi 

实操66:现已知福建的经纬度为为25.54N,118.18E,求第七个数据库中距离福建1000公里内有哪些收录在China键中的城市。

georadius China 118.18 25.54 1000 km

运行结果如下:


3.9、Hyperloglog

概述:在我们做站点流量统计的时候一般会统计页面UV(独立访客:unique visitor)和PV(即页面浏览量:page view)。redis HyperLogLog是用来做基数统计的算法,HyperLogLog的优点是在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的(每个键所占空间固定为12kb)。

基数:如有数据集{1,2,5,5,7,9},那么这个数据集的基数集为{1,2,5,7,9},基数(不重复元素)为5。基数估计就是在误差可接受的范围内,快速计算基数。

使用场景:基数不大,数据量不大就用不上,会有点大材小用浪费空间,有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么,和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmaps 方便很多,一般可以bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃。Hyperloglog常用于网站PV统计,网站UV统计,统计访问量,统计在线用户数,不同词条的搜索次数,文章真实阅读量等。

3.9.1、pfadd

概述:pfadd用于将所有元素参数添加到 Hyperloglog 数据结构中。

语法

pfadd 键名 元素1 元素2 ...

实操67:清空第8个数据库中的数据,创建一个键名为blog的Hyperloglog类型的数据结构,并向里面添加多条数据,每条数据代表该博客被其他用户查看的记录。

pfadd blog niko donk muxi donk muxi

运行结果如下:

注意:添加元素到HyperLogLog中,如果内部有变动返回1,没有变动就返回0。

3.9.2、pfcount

概述:pfcount用于计算Hyperloglog 近似基数,可以计算多个Hyperloglog ,统计基数总数。

语法

pfcount 键名1 键名2...

实操68:基于实操67的数据,计算出有多少个用户浏览过第8个数据库中的博客(blog)。

pfcount blog

运行结果如下:

实操69:在第8个数据库中新建一个名为blog2的Hyperloglog类型的数据结构,并向里面添加多条数据,每条数据代表该博客被其他用户查看的记录,最后统计两个博客共有多少个不同的用户查看

# 创建一个名为blog2的Hyperloglog数据结构并添加多条数据
pfadd blog2 magixx muxi donk zywoo

# 统计blog和blog2两篇博客共有多少不同的用户查看
pfcount blog blog2

运行结果如下:

3.9.3、pfmerge

概述:pfmerge用于将一个或多个Hyperloglog类型数据合并成一个Hyperloglog类型数据。

语法

pfmerge 合并后的名字 用于合并的数据1 用于合并的数据2 ...

实操70:将第8个数据库中blog1和blog2的数据合并到一起取名为newblog。

# 合并blog和blog2的数据并取名为newblog
pfmerge newblog blog blog2

# 查看blog和blog2的总独立用户
pfcount blog blog2

# 查看新合并的newblog的独立用户数
pfcount newblog

运行结果如下:


4、Redis可视化工具

概述:Redis desktop manager是一个能跨平台使用的开源Redis可视化工具。

4.1、下载并安装Redis Desktop Manager

①、进入其官网下载或通过我的网盘分享下载Redis Desktop Manager。

②、无脑下一步安装Redis Desktop Manager即可。

4.2、关闭防火墙和保护模式

4.2.1、关闭防火墙

        在Redis所在的虚拟机中输入如下命令关闭防火墙:

# 关闭防火墙
systemctl stop firewalld.service

# 关闭防火墙自启
systemctl disable firewalld

# 查看防火墙状态
systemctl status firewalld

运行结果如下:

4.2.2、开启远程连接

        redis的redis.conf文件中默认是只支持本地连接,不支持远程连接,因此需要进入文件将本地连接注释掉,进入redis的目录(/usr/local/redis-7.0.2),通过如下命令编辑redis配置文件:

# 进入redis的根目录
cd /usr/local/redis-7.0.2

# 编辑redis配置文件
vi redis.conf

进入文件后,输入如下语句搜索关键字bind

# 输入完后回车进行搜索
/bind

        知识点补充:文件中有很多bind,通过输入小写字母n跳转到下一个匹配项,搜索到如下内容(找到内容后按 i 键进行输入操作,修改完成后按ESC完成后面的操作):

修改完后的样子:

注释完该语句后不要退出文件,后面还有操作!!!

4.2.3、关闭保护模式

        本操作依然在上一步操作的redis.conf文件中操作,通过如下命令搜索关键字:

# 输入完后按回车进行搜索
/protected

        和开启远程连接中的操作一样,按小写的n跳转到下一个匹配项,直到找到下图所示内容,然后将yes改为no(要修改时按i键进行修改,修改完后按ESC键,再输入:wq将文件保存并退出后即可):

修改后的样子:

4.2.4、暴力重启Redis服务

# 通过lsof查看redis端口的进程
lsof -i:6379

# 杀掉通过lsof获取的进程号
kill -9 获取到的PID

运行结果如下:

然后进入redis目录启动Redis服务即可。

4.3、可视化工具连接Redis

4.3.1、获取虚拟机IP

通过如下命令获取Redis所在虚拟机的IP:

vi /etc/sysconfig/network-scripts/ifcfg-ens33

记录Redis虚拟机的IP地址(IPADDR对应的内容):

4.3.2、配置可视化工具

打开Redis Desktop Manager并点击左下角附近的Connect to Redis Server,如下图:

④、按照下图填写连接Redis的配置信息:

4.3.3、遇到的问题

在我连接的过程中出现了一个小插曲,完成上面的步骤后我连不上我的redis,报错如下:Cannot load databases.

将上面的步骤全部重新走了一遍没用,windows ping 虚拟机没问题,虚拟机 ping baidu也没问题,最后发现是虚拟机的IP地址(192.168.70.1)占用了广播地址(这是关于网络的问题),进入虚拟机通过如下命令修改IP地址即可:

vim /etc/sysconfig/network-scripts/ifcfg-ens33

修改IPADDR的值即可,主机号不要占用0~255中最前面几个值和最后面几个值(这里我将1改成了10):

修改完后直接通过如下命令重启网络即可:

systemctl restart network.service

然后再进入软件重新配置我们修改的IP地址即可,点击ok进行连接

单击我们连接的数据库就能看到我们数据库中默认的16张表:


5、Redis配置文件

概述:在Redis的解压目录下有个很重要的配置文件 redis.conf ,关于Redis的很多功能的配置都在此文件中完成的,一般为了不破坏安装的文件,出厂默认配置最好不要去改。

5.1、units单位

概述:配置大小单位,开头定义基本度量单位,只支持bytes,大小写不敏感。

5.2、INCLUDES

概述:Redis只有一个配置文件,如果多个人进行开发维护,那么就需要多个这样的配置文件,这时候多个配置文件就可以在此通过 include /path/to/local.conf 配置进来,而原本的 redis.conf 配置文件就作为一个总闸。

5.3、NETWORK

参数说明

①、bind参数用于绑定redis服务器网卡IP,默认为127.0.0.1,即本地回环地址。这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接。如果bind选项为空的话,那会接受所有来自于可用网络接口的连接。

②、port用于指定redis运行的端口,默认是6379。由于Redis是单线程模型,因此单机开多个Redis进程的时候会修改端口。

③、timeout用于设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接。默认值为0,表示不关闭。

④、tcp-keepalive的单位是秒,表示将周期性的使用SO_KEEPALIVE检测客户端是否还处于健康状态,避免服务器一直阻塞,官方给出的建议值是300s,如果设置为0,则不会周期性的检测。

5.4、GENERAL

参数说明

①、daemonize设置为yes表示指定Redis以守护进程的方式启动(后台启动),默认值为 no。

②、pidfile用于配置PID文件路径,当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面。

③、loglevel用于定义日志级别。默认值为notice,有如下4种取值:

debug(记录大量日志信息,适用于开发、测试阶段)

verbose(较多日志信息)

notice(适量日志信息,使用于生产环境)

warning(仅有部分重要、关键信息才会被记录)

④、logfile用于配置log文件地址,默认打印在命令行终端的窗口上。

⑤、databases用于设置数据库的数目。默认的数据库是DB 0 ,可以在每个连接上使用select 命令选择一个不同的数据库,dbid是一个介于0到databases - 1 之间的数值。默认值是 16,也就是说默认Redis有16个数据库。

5.5、SNAPSHOTTING

概述:本部分用于配置持久化操作。

参数说明

save是用来配置触发 Redis 的持久化条件,也就是什么时候将内存中的数据保存到硬盘。

save 3600 1:表示3600 秒内如果至少有 1 个 key 的值变化,则保存; save 300 10:表示300 秒内如果至少有 10 个 key 的值变化,则保存; save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存。

5.6、REPLICATION

概述:REPLICATION部分用于配置Redis集群。

参数说明

①、slave-serve-stale-data的默认值为yes,当一个 slave(从机) 与 master(主机) 失去联系,或者复制正在进行的时候,slave 可能会有两种表现:

        ①、如果为 yes ,slave 仍然会应答客户端请求,但返回的数据可能是过时,或者数据在第一次同步的时候可能是空的;

        ②、如果为 no ,在执行除了 info he salveof 之外的其他命令时,slave 都将返回一个 "SYNC with master in progress" 的错误。

②、slave-read-only用于配置Redis的Slave实例是否接受写操作,即Slave是否为只读Redis,默认值为yes。

③、repl-diskless-sync表示主从数据复制是否使用无硬盘复制功能,默认值为no。

④、repl-diskless-sync-delay表示当启用无硬盘备份时,服务器等待一段时间后才会通过套接字向从机传送RDB文件,并且这个等待时间是可配置的。

⑤、repl-disable-tcp-nodelay表示同步之后是否禁用从机上的TCP_NODELAY, 如果你选择yes,redis会使用较少量的TCP包和带宽向从机发送数据。

5.7、SECURITY

概述:本部分配置信息用于Redis的安全设置。

参数说明:requirepass用于设置redis连接密码。

5.8、CLIENTS

参数说明:maxclients用于设置客户端最大并发连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件。 描述符数-32(redis server自身会使用一些),如果设置 maxclients为0 。表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

5.9、MEMORY MANAGEMENT

参数说明

①、maxmemory用于设置Redis的最大内存,如果设置为0 。表示不作限制。通常是配合下面介绍的maxmemory-policy参数一起使用。

②、maxmemory-policy :当内存使用达到maxmemory设置的最大值时,redis使用的内存清除策略。有以下几种可以选择:

        1、volatile-lru 利用LRU算法移除设置过过期时间的key(LRU:最近使用 Least Recently Used);

        2、allkeys-lru 利用LRU算法移除任何key;

        3、volatile-random 移除设置过过期时间的随机key;

        4、allkeys-random 移除随机key;

        5、volatile-ttl 移除即将过期的key(minor TTL);

        6、noeviction noeviction 不移除任何key,只是返回一个写错误 ,默认选项。

③、maxmemory-samples :LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法(为了节省内存)。随意你可以选择样本大小进行检,redis默认选择3个样本进行检测,你可以通过maxmemory-samples进行设置样本数。


6、发布订阅

概述:Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

使用场景:博客推送,聊天室等。

注意:从本章起,将使用xshell远程连接redis所在的虚拟机进行操作(xshell更适合多窗口操作)

6.1、订阅

语法

subscribe 主题名字1 [主题名字2 ...]

6.2、发布

语法

publish 主题名 内容

实操71:利用xshell远程连接Redis所在虚拟机三次,三个连接分别创建两个订阅者和一个发布者,两个订阅者都订阅一个名为python的主题,然后发布者发布python主题的相关内容。

①、首先用第一个连接创建第一个订阅者:

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 启动redis
redis-server ../redis.conf

# 打开redis客户端
redis-cli

# 订阅python主题
SUBSCRIBE python

运行结果如下:

②、(第一个连接不要关闭)第二个连接订阅python主题:

在新增的连接中输入如下命令:

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 启动redis
redis-server ../redis.conf

# 打开redis客户端
redis-cli

# 订阅python主题
SUBSCRIBE python

运行结果如下:

③、(前面的连接都不要关闭)在第三个连接中创建一个发布者发布python主机及其内容:

# 进入redis的src目录
cd /usr/local/redis-7.0.2/src/

# 启动redis
redis-server ../redis.conf

# 打开redis客户端
redis-cli

# 发布主题及其内容
publish python hiBro

运行结果如下:

当发布者发布主题后,立即查看两个订阅者的连接,结果如下(消息订阅者都收到了订阅过的主题及其内容):


7、慢查询

概述:慢查询就是比较慢的查询,主要用于定位系统存在的慢操作。

7.1、Redis命令执行过程

说明

①、慢查询发生在第3阶段。

②、客户端超时不一定慢查询,但慢查询是客户端超时的一个可能因素。

③、慢查询日志存放在Redis内存列表中。


7.2、慢查询日志

概述:慢查询日志是Redis服务端在命令执行前后计算每条命令的执行时长,当超过某个阈值是记录下来的日志。日志中记录了慢查询发生的时间,还有执行时长、具体什么命令等信息,它可以用来帮助开发和运维人员定位系统中存在的慢查询。


7.3、慢查询日志获取

概述:可以使用slowlog get命令获取慢查询日志,在slowlog get后面还可以加一个数字,用于指定获取慢查询日志的条数。

实操72:清空数据库中所有的数据(为慢查询日志提供数据),然后获取三条慢查询日志记录。

# 清空所有数据(如果数据库中的数据重要就跳过这一步)
flushall

# 获取3条慢查询日志中的记录
slowlog get 3

运行结果如下:

结果解析

①、第1行代表慢查询记录中的唯一标识ID。

②、第2行代表命令执行的时间戳。

③、第3行代表命令的执行时长。

④、第4行是记录什么命令导致慢查询。

⑤、第5行是记录产生慢查询的客户端。

⑥、第6行用于记录导致慢查询的命令所带的参数。


7.4、获取日志长度

概述:可以使用slowlog len命令查询慢查询日志中日志的总长度。

实操73:查看当前慢查询日志的总长度。

slowlog len

运行结果如下:


7.5、配置慢查询参数

7.5.1、查看慢查询配置

语法

 config get slow*

实操74:获取当前慢查询的配置信息。

config get slow*

运行结果如下:

结果分析

①、前两行是一组数据,表示慢查询的阈值为10000微秒(10毫秒),执行时间超过这个阈值的语句将被记录;

②、第3行和第4行是一组数据,表示该日志最多能保存128条数据。

7.5.2、修改慢查询参数(修改redis配置文件)

概述:本小节用于展示通过修改redis.conf文件实现修改慢查询参数。

实操75:通过修改redis.conf文件实现慢查询的阈值为1000微秒。

# 进入redis核心配置文件所在目录
cd /usr/local/redis-7.0.2/

# 编辑核心配置文件
vim redis.conf

# 通过如下命令搜索关键字定位到参数修改处
/slowlog

# 将slowlog-log-slower-than后的参数改为1000
slowlog-log-slower-than 1000

# 保存并退出文件
ESC键 
:wq

# 关闭Redis服务(建议暴力解决)
lsof -i:6379
kill -9 查询到的PID

# 开启redis服务
cd /usr/local/redis-7.0.2/src
redis-server ../redis.conf
redis-cli

# 验证是否生效
config get slow*

核心配置文件修改图如下:

关闭Redis服务参考图如下:

验证图如下(slowlog-log-slower-than的参数成功改为了1000):

7.5.3、修改慢查询参数(通过命令实现)

语法

config set 参数名1 参数对应的值1 [参数名2 参数对应的值2 ...]

实操76:通过命令的方式将慢查询的阈值修改为10000微秒,日志保存数量增加到256条。

# 将慢查询阈值设置为10毫秒,保存记录的条数设置为256条
CONFIG set slowlog-log-slower-than 10000 slowlog-max-len 256

# 验证是否生效
config get slow*

运行结果如下:

注意:通过命令修改慢查询的参数不需要重启redis服务即可生效,但通过修改redis核心配置文件实现慢查询参数的修改需要重启redis服务才能生效。


7.6、使用建议

7.6.1、slowlog-max-len

①、线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。

②、增大慢查询列表可以减缓慢查询被剔除的可能,例如线上可设置为1000以上。

7.6.2、slowlog-log-slower-than

①、默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值

②、由于Redis采用单线程响应命令,对于高流量的场景,如果命令执行时间在1毫秒以上,那么Redis最多可支撑OPS不到1000。因此对于高OPS场景的Redis建议设置为1毫秒


8、Redis数据安全

8.1、初识持久化机制

概述:由于Redis的数据都存放在内存中,如果没有配置持久化,Redis重启后数据就全丢失了,于是需要开启Redis的持久化功能,将数据保存到磁盘上,当Redis重启后,可以从磁盘中恢复数据。

持久化的意义:主要在于故障恢复。比如部署了一个redis,作为cache缓存,同时也可以保存一些比较重要的数据。

Redis提供的持久化方式:①、RDB(Redis DataBase) ;②、AOF(Append Only File)。


8.2、RDB持久化机制

概述:RDB持久化机制指在规定的时间间隔内将内存的数据集快照写入磁盘,恢复时是将快照文件直接读到内存里。

注意:RDB是经过压缩的二进制文件。

8.2.1、RDB的三种触发方式

8.2.1.1、修改redis.conf文件中的RDB配置信息

概述:首先进入redis目录下编辑redis.conf文件,进入文件后通过如下命令搜索关键字save,按小写字母 n 跳转到下一个匹配项,直到找到如图所示的位置:

# 进入redis目录
cd /usr/local/redis-7.0.2/

# 编辑核心配置文件
vim redis.conf

# 搜索关键字save
/save

# 按小写字母n进行跳转

        此时可以发现原有的配置中写了三对参数(但是被注释了),即save 3600 1表示3600秒内有一个数据发生变化就触发RDB,save 300 100 表示 300秒内有100个数据发生变化就触发RDB,save 60 10000表示60秒内有10000个数据发生变化就触发RDB。

        为了后期测试,这里为核心配置文件添加一个RDB触发条件:10秒内有两个数据发送变化就触发RDB,修改后的截图如下:

# 首先按i开始编辑文件
i

# 插入10秒内有2条数据的变化就触发RDB的语句
save 10 2

# 保存并退出文件
ESC 
:wq

        接下来验证核心配置文件,如果已经启动过redis,首先需要重启Redis(建议使用lsof查看redis的端口被哪些进程使用,然后通过杀进程的方式实现强制关闭redis,然后再去src目录启动redis即可)

# 通过lsof查看redis端口被哪些进程占用(如果没有结果就说明redis没有启动,直接去启动redis即可)
lsof -i:6379

# 杀掉通过lsof获取到的进程号(如果lsof没有返回结果请忽略此步骤)
kill -9 获取到的PID

# 启动redis
cd /usr/local/redis-7.0.2/src/
redis-server ../redis.conf

# 连接redis客户端
redis-cli

# 10秒内插入任意两条数据
set a 1
set b 2

当数据操作成功后,我们可以去验证是否出发了RDB。

知识点补充:在redis.conf文件中有提到RDB保存的文件默认叫dump.rdb,redis7.0.2版本默认保存redis根目录下的src目录中:

保存的数据如下(正如前面说的,RDB是经过压缩的二进制文件):

8.2.1.2、flushall命令触发RDB

概述:执行flushall命令,也会触发rdb规则。

8.2.1.3、save & bgsave

概述:可以通过命令手动触发Redis的RDB持久化机制。

save:该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止,不建议使用。

bgsave:执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。

# 连接redis客户端
redis-cli

# 使用异步快照操作
bgsave

# 使用save进行快照操作(不推荐,容易造成阻塞)
save

运行结果如下:

8.2.2、高级配置

8.2.2.1、stop-writes-on-bgsave-error

概述:默认值是yes。当Redis无法写入磁盘时,直接关闭Redis的写操作。

8.2.2.2、rdbcompression

概述:默认值是yes,对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。

8.2.2.3、rdbchecksum

概述:默认值是yes,在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

知识点补充:只需要将rdb文件(dump.rdb)放在Redis的启动目录,Redis启动时会自动加载dump.rdb并恢复数据。

8.2.3、RDB的优缺点

优点

①、适合大规模的数据恢复;

②、适合对数据完整性和一致性要求不高的场景使用;

③、节省磁盘空间;

④、恢复速度快。

缺点:备份周期是在一定间隔时间的基础上做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有的修改。


8.3、AOF持久化机制

概述:AOF持久化机制是以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来。

8.3.1、允许AOF开启

概述:RDB默认是开启的,但AOF默认是不开启的,可以在redis.conf中配置文件名称,redis-7.0.2版本中文件默认叫appendonly.aof.1.incr.aof。

注意:redis-7.0.2版本的AOF文件会保存到位于启动redis时所处目录下一个名为appendonlydir的目录中,如果AOF和RDB同时启动,Redis默认读取AOF的数据。

实操77:允许AOF开启。

# 进入redis目录
cd /usr/local/redis-7.0.2/

# 编辑核心配置文件
vim redis.conf

# 搜索关键字aof
/aof

# 按小写字母 n 跳转到下一个匹配项,直到找到符合下面图片的位置
n

# 将appendonly后的no改为yes即可开启AOF
i # 编辑文本
yes # 删掉no,再写yes

# 保存文件并退出
ESC
:wq

运行结果如下:

接下来重启redis并插入几条数据,查看是否存在appendonly.aof文件:

# 获取redis端口的进程号
lsof -i:5379

# 通过杀掉redis的进程实现强制关闭redis
kill -9 通过lsof获取的PID

# 开启redis
cd /usr/local/redis-7.0.2/src
redis.server ../redis.conf

# 连接客户端
redis-cli

# 随机插入几条数据
set var1 123
set var2 456

# 关闭redis客户端并查看是否存在aof文件
Ctrl+C
ll appendonlydir/appendonly.aof.*
cat appendonlydir/appendonly.aof.1.incr.aof

运行结果如下:

8.3.2、AOF同步频率设置

概述:可以通过核心配置文件中的appendfsync来设置同步频率。

appendfsync always:表示始终同步,每次Redis的写入都会立刻记入日志,性能较差但数据完整性比较好。

appendfsync everysec:表示每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。

appendfsync no:表示redis不主动进行同步,把同步时机交给操作系统。

实操78:将AOF的同步频率修改为始终同步。

# 进入配置文件所处目录
cd /usr/local/redis-7.0.2

# 编辑配置文件
vim redis.conf

# 搜索关键字appendfsync
/appendfsync

# 修改为如下图所示内容即可保存退出
ESC
:wq

修改后的截图如下:

重启redis使配置文件生效:

# 获取redis进程号(PID)
lsof -i:6379

# 关闭redis进程实现强制关闭
kill -9 通过lsof获取的PID

# 进入redis的src目录启动redis
cd /usr/local/redis-7.0.2/src
redis-server ../redis.conf

参考截图如下:

实操79:当误删了redis数据库的数据后,尝试使用AOF恢复所有数据。

# 连接redis客户端
redis-cli

# 切换到第二个数据库
select 1

# 插入任意数据
set var1 niko
set var2 zywoo

# 清空当前数据库所有数据
flushdb

# 断开redis客户端连接
Ctrl + C

# 编辑AOF文件
vim  appendonlydir/appendonly.aof.1.incr.aof

参考截图如下:

删除文件中zywoo后所有的数据后保存退出即可即可:

删除后的结果如下:

接下来重启redis,使redis重新加载aof文件,实现数据同步:

# 关闭redis
lsof -i:6379

kill -9 PID

# 启动redis
cd /usr/local/redis-7.0.2/src

redis-server ../redis.conf

# 连接redis客户端
redis-cli

# 如果同步不成功可以写如下命令
BGREWRITEAOF

# 查看被删除的键
select 1
keys *

参考截图如下:

8.3.3、AOF的优缺点

优点

①、AOF的持久化机制相对于RDB机制来说,AOF的备份机制更稳健,丢失数据概率更低;

②、AOF是可读的日志文本,通过操作AOF更稳健,可以处理误操作。

缺点

①、AOF的持久化机制相对于RDB机制来说,AOF占用更多的磁盘空间;

②、AOF的恢复备份速度要慢。

③、如果AOF每次读写都同步的话,会有一定的性能压力。


8.4、持久化机制的使用建议

8.4.1、不要只用RDB

概述:RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦redis进程宕机,那么至少会丢失最近5分钟甚至更长时间的数据。

8.4.2、不要只用AOF

概述

①、RDB做冷备比AOF做冷备的恢复速度更快。

②、RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug。

知识点补充1:冷备是一种数据备份方法,通常指在数据不活跃或者不可修改状态下进行的备份。冷备份通常发生在系统或者服务处于停机或者非活跃状态时,这样可以确保备份的数据是一个静态且完整的快照。

知识点补充2:在redis-7.0.2版本中,如果rdb文件受损,可以通过redis中src目录下的redis-check-rdb文件进行修复;如果aof文件受损,可以通过redis中src目录下的redis-check-aof文件进行修复。

8.4.3、综合使用RDB和AOF

概述:用AOF来保证数据不丢失,作为数据恢复的第一选择,用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。


9、Redis事务

9.1、初识redis事务

数据库中的事务:在数据库层面,事务是指一组操作,这些操作要么全都被成功执行,要么全都不执行。

数据库事务的四大特性

①、A:Atomic,原子性,将所有SQL作为原子工作单元执行,要么全部执行,要么全部不执行;

②、C:Consistent,一致性,事务完成后,所有数据的状态都是一致的,即A账户只要减去了100,B账户则必定加上了100;

③、I:Isolation,隔离性,如果有多个事务并发执行,每个事务作出的修改必须与其他事务隔离;

④、D:Duration,持久性,即事务完成后,对数据库数据的修改被持久化存储。

redis事务:Redis事务是一组命令的集合,一个事务中的所有命令都将被序列化,按照一次性、顺序性、排他性的执行一系列的命令。

redis事务的三大特性

①、单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断;

②、没有隔离级别:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在 "事务内的查询要看到事务里的更新,在事务外查询不能看到"。

③、不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚;

redis事务执行的三个阶段

①、开启:以 multi 开始一个事务;

②、入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面;

③、执行:由 exec 命令触发事务。


9.2、事务基本操作

概述:事务从输入Multi命令开始,输入的命令都会依次压入命令缓冲队列中,但并不会执行,直到输入Exec后,Redis会将之前的命令缓冲队列中的命令依次执行。组队过程中,可以通过discard来放弃组队。

实操80:开启一个事务,放入任意一个键,对它的值进行累加,最后提交事务并获取该键的最终值。

# 开启事务
multi

# 新建一个键为num1,值为1的键值对
set num1 1

# 对num1做累加
incr num1 
incr num1
incr num1

# 提交事务
exec

# 获取num1最终的结果
get num1

运行结果如下:

实操81:开启一个事务,事务中对num1做累加,然后用discard放弃组队,最后获取num1的值。

# 开启事务
multi

# 对num1做累加
incr num1
incr num1
incr num1

# 取消组队
discard

# 获取num1的值
get num1

运行结果如下:

实操82:演示事务中存在语法错误的情况。

# 开启事务
multi

# 写一个错误的语句
set muxi

# 再写一个正确的错误
set muxi 123

# 提交事务
exec

运行结果如下:

总结:当Redis事务中存在语法错误时,提交事务后整个事务都会报错。

实操83:演示事务中存在非语法错误的情况。

# 开启事务
multi

# 为事务中添加多条语句
get num1 
incr num1
set gmail muxi@gmail.com
incr gmail # incr只能加内容为数字的字符串,因此这里会报错,但这里不是语法上的错误,所以不会直接报错
get gmail

# 提交事务
exec

运行结果如下:

总结:事务中存在非语法错误时,正确命令都会执行,错误命令返回错误。


10、Redis集群

10.1、初识主从复制

背景:在现有企业中绝大部分使用的是redis单机服务,在实际的场景当中单一节点的redis容易面临风险。

面临的问题

①、机器故障。我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移到另外一台服务器并且要保证数据是同步的。

②、容量瓶颈。当我们有需求需要扩容 Redis 内存时,单机可以轻松的从 16G 的内存升到 64G,但如果需要256G或者更多内存该怎么解决呢?

解决办法:要实现分布式数据库的更大的存储容量和承受高并发访问量,我们会将原来集中式数据库的数据分别存储到其他多个网络节点上。

注意:Redis 为了解决这个单一节点的问题,也会把数据复制多个副本部署到其他节点上进行复制,实现 Redis的高可用,实现对数据的冗余备份从而保证数据和服务的高可用。

主从复制:主从复制指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。

主从复制的作用

①、数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

②、故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。

③、负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。

④、高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。


10.2、主从复制搭建

声明:本节只是为了让大家了解redis集群搭建的大致过程,主从复制是在同一个虚拟机内实现的,如果是实际的生产环境,其实可以按照本文的实现思路照猫画虎,将不同的配置文件放在不同的虚拟机中实现。

①、关闭redis

# 查看进程号(PID)
lsof -i:6379

# 通过杀掉进程号达到强制关闭redis的效果
kill -9 PID(这里指通过lsof获取到的进程号)

运行结果如下:

②、在redis目录下新建一个名为redis6379的配置文件

# 进入redis目录下
cd /usr/local/redis-7.0.2/

# 通过vim创建一个名为redis6379.conf的文件
vim redis6379.conf

参考截图如下:

配置文件内容如下:

include /usr/local/redis-7.0.2/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

③、将redis6379.conf文件复制两份分别命名为redis6380.conf和redis6381.conf,并修改文件内容

redis6380.conf内容如下:

include /usr/local/redis-7.0.2/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb

redis6381.conf内容如下:

include /usr/local/redis-7.0.2/redis.conf
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb

④、启动三台redis服务器

# 进入redis启动文件的目录
cd /usr/local/redis-7.0.2/src/

# 启动端口号为6379,6380和6381的redis
redis-server ../redis6379.conf
redis-server ../redis6380.conf
redis-server ../redis6381.conf

# 验证三台redis服务器是否启动成功
ps aux | grep redis

运行结果如下:

⑤、XShell通过不同窗口连接不同的redis服务器(对同一台虚拟机连接了三次,模拟三台虚拟机对应不同的redis服务器)

在第一个窗口中输入如下命令:

redis-cli -p 6379

运行结果如下:

在第二个窗口中输入如下命令:

cd /usr/local/redis-7.0.2/src/
redis-cli -p 6380

运行结果如下:

在第三个窗口中输入如下命令:

cd /usr/local/redis-7.0.2/src/
redis-cli -p 6381

运行结果如下:

⑥、配从库(将6380和6381端口作为从机)

概述:redis通过slaveof配置redis集群中该虚拟机属于哪一台虚拟机的从机,用这种方式来确认哪些虚拟机是主机,哪些虚拟机是从机,只有从机需要配。

语法

slaveof  <ip> <port>

在6380端口和6381端口的虚拟机执行如下语句:

slaveof 127.0.0.1 6379

运行结果如下:

⑦、获取当前redis实例的信息

对每台虚拟机执行如下语句:

info replication

6379端口的虚拟机运行结果如下:

6380端口的虚拟机运行结果如下:

6381端口的虚拟机运行结果如下:

⑧、验证主从复制

首先进入6379端口的虚拟机(主机)清空数据库中的所有的数据:

flushall

然后插入任意两条数据:

set num1 1
set num2 2

运行结果如下:

在6380端口的虚拟机获取num1的数据:

get num1

运行结果如下:

在6381端口的虚拟机获取num2的数据:

get num2

运行结果如下:

至此,我们的主从复制就搭建完成了!


10.3、主从复制原理

概述:主从复制分为3个阶段,6个过程。

三个阶段:①、连接建立阶段(或者说准备阶段);②、数据同步阶段;③、命令传播阶段。

六个过程

①、保存主节点(master)信息

②、从节点与主节点建立网络连接从节点会建立一个 socket 套接字,从节点建立了一个端口为51234的套接字,专门用于接受主节点发送的复制命令。

③、发送ping命令连接建立成功后从节点发送 ping 请求进行首次通信。

作用:①、检测主从之间网络套接字是否可用。②、检测主节点当前是否可以接受命令 。

④、权限验证:如果主节点在redis.conf核心配置文件中设置了 requirepass 的参数,则需要密码验证,从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证;如果验证失败复制将终止,从节点重新发起复制流程。

⑤、同步数据集:主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最长的步骤。

主从同步策略:主机与从机刚开始连接的时候,进行全量同步;全量同步结束后,进行增量同步。如果有需要,slave 在任何时候都可以发起全量同步。redis 的策略是首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

⑥、命令持续复制:当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。


10.4、初识哨兵监控

背景:在主从复制中出现了如下问题:一旦主节点宕机,写服务无法使用,就需要手动去切换,重新选取主节点,手动设置主从关系。

主从切换:当redsi的主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,我们优先考虑哨兵模式

哨兵模式:哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

注意:多个哨兵也是为了预防单点故障,防止哨兵宕机。

哨兵的作用

①、集群监控:负责监控redis master和slave进程是否正常工作

②、消息通知:如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员

③、故障转移:如果master node挂掉了,会自动转移到slave node上

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


10.5、配置哨兵监控

概述:本小节将配置三个哨兵用于监控主节点。

①、在redis目录下创建名为sentinel-26379.conf的哨兵配置文件

在主机输入如下命令:

# 进入redis目录
cd /usr/local/redis-7.0.2/

# 创建一个名为sentinel-26379.conf的配置文件并编辑
vim sentinel-26379.conf

参考截图如下:

编辑内容如下:

# 端口
port 26379
# 守护进程运行
daemonize yes
# 日志文件
logfile "26379.log"
sentinel monitor mymaster 127.0.0.1  6379 2

参数说明:sentinel monitor mymaster 127.0.0.1 6379 2 含义是:该哨兵节点监控 127.0.0.1(本机)这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

②、复制两份sentinel-26379.conf文件,分别重命名为sentinel-26380.conf和sentinel-26381.conf

在主机输入如下命令:

cp sentinel-26379.conf sentinel-26380.conf
cp sentinel-26379.conf sentinel-26381.conf

编辑sentinel-26380.conf文件,内容如下

# 端口
port 26380
# 守护进程运行
daemonize yes
# 日志文件
logfile "26380.log"
sentinel monitor mymaster 127.0.0.1  6379 2

编辑sentinel-26380.conf文件,内容如下

# 端口
port 26381
# 守护进程运行
daemonize yes
# 日志文件
logfile "26381.log"
sentinel monitor mymaster 127.0.0.1  6379 2

③、启动哨兵节点

知识点补充:启动哨兵节点的两种方式:

# 方式一
redis-sentinel ../sentinel-26379.conf

# 方式二
redis-server  ../sentinel-26379.conf --sentinel

在主机输入如下命令,进入redis下的src目录,分别启动三台哨兵:

# 进入redis目录下的src目录
cd /usr/local/redis-7.0.2/src/

# 启动三台哨兵
redis-sentinel ../sentinel-26379.conf
redis-server ../sentinel-26380.conf --sentinel
redis-sentinel ../sentinel-26381.conf

运行结果如下:

④、查看哨兵节点状态

通过如下命令连接哨兵并查看其状态:

# 连接哨兵
redis-cli -p 26379

# 查看哨兵状态
info sentinel

运行结果如下:


10.6、哨兵监控原理

①、监控阶段

概述:哨兵节点会定期检查主节点和其他哨兵节点的状态。

sentinel(哨兵1)----->向master(主)和slave(从)发起info,拿到全信息。

sentinel(哨兵2)----->向master(主)发起info,就知道已经存在的sentinel(哨兵1)的信息,并且连接slave(从)。

sentinel(哨兵2)----->向sentinel(哨兵1)发起subscribe(订阅)。

②、通知阶段

概述:sentinel不断的向master和slave发起通知,收集信息。

③、故障转移阶段(选举领头哨兵)

概述:如果多个哨兵同时检测到主节点失联,会进行一个领头哨兵的选举过程。这个过程通过Raft算法实现。被选为领头的哨兵节点将负责执行故障转移(failover)。

(通知阶段sentinel发送的通知没得到master的回应,就会把master标记为SRI_S_DOWN,并且把master的状态发给各个sentinel,其他sentinel听到master挂了,说我不信,我也去看看,并把结果共享给各个sentinel,当有一半的sentinel都认为master挂了的时候,就会把master标记为SRI_0_DOWN。)

④、选择新的主节点

概述:领头哨兵节点会根据一定的规则选择一个从节点(slave)来提升为新的主节点;选择规则通常包括:从节点的优先级(由配置的slave-priority中决定)、从节点的复制偏移量(即与原主节点的数据同步情况)、从节点的连接状态等。通常情况下,优先级高的从节点会优先被选为新的主节点;如果优先级相同,则选择复制偏移量最大的从节点。

⑤、通知和配置更新

概述:领头哨兵节点会通知所有哨兵和从节点关于新的主节点的决定,并且所有从节点会开始复制新的主节点,而且哨兵节点会更新它们的配置文件,以反映新的主节点信息。

总结:Redis哨兵模式通过分布式一致性算法确保在主节点故障时,能够选出一个最佳的从节点来成为新的主节点,以确保服务的高可用性和数据一致性


10.7、故障转移

①、查看6379端口的信息

# 连接redis服务器的6379端口
redis-cli -p 6379

# 查看当前端口的信息
info replication

运行结果如下:

通过上面的信息可知,slave0和slave1的优先级相同,slave0的偏移量(offset)大于slave1,因此当master宕机后,slave0(即6381端口的从机)有很大的概率当选为新的master。

②、干掉master进程

# 获取6379的进程号(PID)
lsof -i:6379

# 杀掉6379的进程号
kill -9 获取的PID

运行结果如下:

③、查看26379端口的哨兵信息

# 连接26379端口的哨兵
redis-cli -p 26379

# 获取哨兵信息
info sentinel

运行结果如下:

从上图可知,master(6379端口)宕机后,哨兵将6381端口的从机选举成新的master。

注意:主节点不会立马切换过来,因为哨兵发现主节点故障并将故障转移需要一段时间。

④、再次启动6379端口,查看其是否能恢复成主节点

# 再次开启6379端口的连接
redis-server ../redis6379.conf

# 连接6379端口的客户端
redis-cli -p 6379

# 查看当前端口服务器的信息
info replication

运行结果如下:

从上图的role:slave可知,即使6379端口恢复后,并不会成为master,而是成为了slave。

⑤、配置文件被改写

概述:故障转移阶段,哨兵和主从节点的配置文件都会被改写

# 进入redis6379.conf配置文件所在目录
cd /usr/local/redis-7.0.2/

# 查看配置文件信息
cat redis6379.conf

运行结果如下:

总结

①、哨兵系统中的主从节点,与普通的主从节点并没有什么区别,故障发现和转移是由哨兵来控制和完成的。

②、哨兵节点本质上是redis节点。

③、每个哨兵节点只需要配置监控主节点,就可以自动发现其他的哨兵节点和从节点。

④、在哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写(config rewrite)。


10.8、初识Cluster模式(Redis集群)

Redis中的集群模式:①、主从模式;②、Sentinel模式(哨兵模式);③、Cluster模式。

哨兵模式的缺点

①、当master挂掉的时候,sentinel 会选举出来一个 master,选举的时候是没有办法去访问Redis的,会存在访问瞬断的情况;

②、哨兵模式,对外只有master节点可以写,slave节点只能用于读,尽管Redis单节点最多支持10W的QPS,但是在电商大促的时候,写数据的压力全部在master上。

③、Redis的单节点内存不能设置过大,若数据过大在主从同步将会很慢;在节点启动的时候,时间特别长。

cluster模式:Redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。

cluster模式的优点

①、Redis集群有多个master,可以减小访问瞬断问题的影响;

②、Redis集群有多个master,可以提供更高的并发量;

③、Redis集群可以分片存储,这样就可以存储更多的数据。


10.9、Cluster模式搭建

概述:Redis的集群搭建最少需要3个master节点,下面搭建3个master,每个master下面挂1个slave节点,总共6个Redis节点;

10.9.1、环境准备

①、准备一个新装Redis的虚拟机,将其克隆两份

说明:我的redis依然装在/usr/local目录下,redis文件名为redis-7.0.2。

克隆完虚拟机后通过如下命令修改每个虚拟机的IP:

vim /etc/sysconfig/network-scripts/ifcfg-ens33
虚拟机名称虚拟机IP占用的端口
Redis192.168.70.108001,8002
Redis1192.168.70.118001,8002
Redis2192.168.70.128001,8002

②、用Xshell连接三台虚拟机

首先要打开三台虚拟机,然后用xshell连接三台虚拟机,参考截图如下:

10.9.2、创建集群文件夹并修改配置文件

注意:以下操作都是同时在三个虚拟机上进行操作。

①、为每台虚拟机创建一个集群专用目录,并将redis目录下的核心配置文件拷贝到每个端口的目录中

在确保连接到三台虚拟机后进行如下操作:工具 --> 发送键输入到(k) --> 所有会话

三台虚拟机都执行如下命令:

# 进入redis所在目录
cd /usr/local/redis-7.0.2/

# 创建一个集群专用目录
mkdir redis-cluster

# 进入新建的目录
cd redis-cluster

# 创建两个端口的目录
mkdir 8001
mkdir 8002


# 将根目录下的redis.conf核心配置文件拷贝一份到redis-cluster/8001目录下
cp ../redis.conf ./8001/

运行结果如下:

②、编辑8001端口中的配置文件

修改redis的端口号:

# 编辑8001目录下的配置文件
vim 8001/redis.conf

# 搜索关键字port
/port

# (按小写字母n跳转到下一个匹配项)大概在136行的位置
n

# (按字母i键进行插入)将6379修改为8001
port 8001

修改后的截图如下:

允许8001端口的Redis服务器在后台允许:

# 退出插入模式
ESC

# 搜索关键字daemonize
/daemonize

# (按以下字母i进入插入模式)
i

# 将no改为yes
daemonize yes

参考截图如下:

修改Redis服务器在启动时生成的PID文件的路径:

# 退出插入模式
ESC

# 搜索关键字pidfile
/pidfile

# (按以下字母i进入插入模式)
i

# 将6379修改为8001
pidfile /var/run/redis_8001.pid

运行结果如下:

修改Redis数据持久化文件的存储目录(不同端口必须指定不同的目录位置,否则会造成数据丢失):

# 退出插入模式
ESC

# 搜索关键字dir
/dir

# (按以下字母i进入插入模式)
i

# 将持久化路径设置为8001目录下
dir /usr/local/redis-7.0.2/redis-cluster/8001/

参考截图如下:

开启集群模式并设置集群节点信息文件:

# 退出插入模式
ESC

# 搜索关键字cluster-enable
/cluster-enable

# (按以下字母i进入插入模式)
i

# 将语句前的井号去掉
cluster-enabled yes

# 设置集群节点信息文件
cluster-config-file nodes-8001.conf

# 修改节点离线的超时时间
cluster-node-timeout 5000

参考截图如下:

允许远程连接(redis默认是只能本地连接):

# 退出插入模式
ESC

# 搜索关键字bind
/bind

# 按几次小写字母n跳转到87行左右
n

# (按以下字母i进入插入模式)
i

# 在bind 127.0.0.1 -::1前面加井号将其注释掉
#bind 127.0.0.1 -::1

参考截图如下:

关闭保护模式:

# 退出插入模式
ESC

# 搜索关键字protected-mode
/protected-mode

# (按以下字母i进入插入模式)
i

# 将yes改为no
protected-mode no

参考截图如下:

开启AOF:

# 退出插入模式
ESC

# 搜索关键字appendonly
/appendonly

# (按以下字母i进入插入模式)
i

# 将no改为yes
appendonly yes

# 退出插入模式
ESC

# 保存并退出文件
:wq

参考截图如下:

③、将8001端口的配置文件拷贝到8002端口的目录并修改:

# 将8001目录中的配置文件拷贝到8002目录中
cp 8001/redis.conf  8002/

# 修改拷贝到8002目录的redis配置文件
vim 8002/redis.conf

参考截图如下:

通过如下命令将所有的8001修改为8002:

# 将文件中所有的8001修改为8002
:%s/8001/8002/g

# 保存并退出文件
:wq

10.9.3、关闭所有虚拟机的防火墙

# 关闭防火墙
systemctl stop firewalld.service

# 关闭防火墙自启
systemctl disable firewalld.service

运行结果如下:

10.9.4、启动集群

# 进入redis启动目录
cd /usr/local/redis-7.0.2/src/

# 启动8001端口的服务器
redis-server ../redis-cluster/8001/redis.conf

# 启动8002端口的服务器
redis-server ../redis-cluster/8002/redis.conf

# 检查redis启动状态
ps -ef | grep redis

参考截图如下:

至此,redis集群的准备工作就完成了,接下来单独操作一个会话即可(关闭发送键盘输入的所有会话):再次点击Xshell的工具 => 发送键输入到 => 当前会话

取消后的样子:

创建一个集群,每台主机下有一台从机(将每台虚拟机的IP及其端口号写入):

# 创建一个redis集群
redis-cli --cluster create  --cluster-replicas 1 192.168.70.10:8001 192.168.70.10:8002 192.168.70.11:8001 192.168.70.11:8002 192.168.70.12:8001 192.168.70.12:8002

# 程序会暂停确认一下
yes

运行结果如下:

通过如下命令查看cluster的用法:

redis-cli --cluster help

运行结果如下:

最后尝试以集群的方式连接ip为192.168.70.11,端口为8001的redis服务器并查看集群信息:

# 以集群的方式连接指定redis服务器
redis-cli -c -h 192.168.70.11 -p 8001

# 查看集群信息
cluster info

运行结果如下:


10.10、Cluster模式实操

概述Redis Cluster将所有数据划分为16384个slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。只有master节点会被分配槽位,slave节点不会分配槽位。

槽定位算法:Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。HASH_SLOT = CRC16(key) % 16384

10.10.1、命令的使用

注意:为redis集群存入一个值后,redis集群会计算出相应的槽值并进行切换节点,存入数据的操作。

实操84:为redis集群中存入一个键值对。

# 存入一个值
set var1 niko

# 存入后所处的机器自动切换到var1所处的机器,因为不自动切换过来就拿不到我们存进来的值
get var1

运行结果如下:

实操85:redis2虚拟机通过集群中192.168.70.12:8001服务器获取实操84中存储的var1的值。

redis-cli -c -h 192.168.70.12 -p 8001

get var1

运行结果如下:

从结果可知,在redis集群中,如果服务器a要获取服务器b的数据,Redis集群会自动切换到服务器b并获取对应数据。

知识点补充:可以通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到同一个slot中。

实操86:在redis集群中,尝试将一组数据放在相同的槽位中。

# 创建一个名为cs的组,大括号前对应组内不同的变量名
mset var1{cs} niko var2{cs} zywoo var3{cs} donk

# 获取cs组中var1变量的值
get var1{cs}

# 获取cs组中var2变量的值
get var2{cs}

# 获取cs组中var3变量的值
get var3{cs}

运行结果如下F:F:

在其他机器获取cs组内的值:

get var1{cs}

运行结果如下:

10.10.2、故障恢复

验证的问题:如果某个master宕机了,是否会有从机顶替master的位置。

查看所有的节点:

cluster nodes

运行结果如下:

将当前节点(192.168.70.10:8001)的进程杀死就会产生该节点宕机的现象:

进入IP为192.168.70.10的虚拟机进行如下操作:

# 查看192.168.70.10虚拟机8001端口的进程号
lsof -i:8001

# 杀掉当前虚拟机8001端口的进程
kill -9 获取的PID

运行结果如下:

然后连接其他redis服务器查看当前所有节点的信息:

redis-cli -c -h 192.168.70.12 -p 8001
cluster nodes

运行结果如下:

从上图可知,192.168.70.10虚拟机的8001端口的redis服务器宕机后,redis集群立马找了slave顶替master的位置。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
尚硅谷是一个教育机构,他们提供了一份关于Redis学习笔记。根据提供的引用内容,我们可以了解到他们提到了一些关于Redis配置和使用的内容。 首先,在引用中提到了通过执行命令"vi /redis-6.2.6/redis.conf"来编辑Redis配置文件。这个命令可以让你进入只读模式来查询"daemonize"配置项的位置。 在引用中提到了Redis会根据键值计算出应该送往的插槽,并且如果不是该客户端对应服务器的插槽,Redis会报错并告知应该前往的Redis实例的地址和端口。 在引用中提到了通过修改Redis的配置文件来指定Redis的日志文件位置。可以使用命令"sudo vim /etc/redis.conf"来编辑Redis的配置文件,并且在文件中指定日志文件的位置。 通过这些引用内容,我们可以得出结论,尚硅谷的Redis学习笔记涵盖了关于Redis的配置和使用的内容,并提供了一些相关的命令和操作示例。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Redis学习笔记--尚硅谷](https://blog.csdn.net/HHCS231/article/details/123637379)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Redis学习笔记——尚硅谷](https://blog.csdn.net/qq_48092631/article/details/129662119)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐曦可期

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值