Redis介绍


一、 Redis介绍

1. NoSQL的引言

NoSQL(Not Only SQL ),意即不仅仅是SQL, 泛指非关系型的数据库。Nosql这个技术门类,早期就有人提出,发展至2009年趋势越发高涨。

2. 为什么是NoSQL

随着互联网网站的兴起,传统的关系数据库在应付动态网站,特别是超大规模和高并发的纯动态网站已经显得力不从心,暴露了很多难以克服的问题。如商城网站中对商品数据频繁查询对热搜商品的排行统计订单超时问题、以及微信朋友圈(音频,视频)存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不是那么乐观。nosql这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是sql。

3. NoSQL的四大分类

1 键值(Key-Value)存储数据库

# 1.说明: 
- 这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。

# 2.特点
- Key/value模型对于IT系统来说的优势在于简单、易部署。  
- 但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。

# 3.相关产品
- Tokyo Cabinet/Tyrant,
- Redis
- SSDB
- Voldemort 
- Oracle BDB

2 列存储数据库

# 1.说明
- 这部分数据库通常是用来应对分布式存储的海量数据。

# 2.特点
- 键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。

# 3.相关产品
- Cassandra、HBase、Riak.

3 文档型数据库

# 1.说明
- 文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高

# 2.特点
- 以文档形式存储

# 3.相关产品
- MongoDB、CouchDB、 MongoDb(4.x). 国内也有文档型数据库SequoiaDB,已经开源。

4 图形(Graph)数据库

# 1.说明
- 图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。
- NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。

# 2.特点

# 3.相关产品
- Neo4J、InfoGrid、 Infinite Graph、

4. NoSQL应用场景

  • 数据模型比较简单

  • 需要灵活性更强的IT系统

  • 对数据库性能要求较高

  • 不需要高度的数据一致性

5. 什么是Redis

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.

Redis 开源 遵循BSD 基于内存数据存储 被用于作为 数据库 缓存 消息中间件

  • 总结: redis是一个内存型的数据库

6. Redis特点

  • Redis是一个高性能key/value内存型数据库

  • Redis支持丰富的数据类型

  • Redis支持持久化

  • Redis单线程,单进程


二、Redis安装和设置

1.安装Redis依赖

Redis是基于C语言编写的,因此首先需要安装Redis所需要的gcc依赖:

yum install -y gcc tcl

2.上传安装包并解压

上传到 /usr/local目录下

解压缩:

tar -xzf redis-6.2.6.tar.gz

进入redis目录:

cd redis-6.2.6

运行编译命令:

make && make install

如果没有出错,应该就安装成功了。

默认的安装路径是在 /usr/local/bin目录下:

该目录以及默认配置到环境变量,因此可以在任意目录下运行这些命令。其中:

  • redis-cli:是redis提供的命令行客户端

  • redis-server:是redis的服务端启动脚本

  • redis-sentinel:是redis的哨兵启动脚本

3.启动

redis的启动方式有很多种,例如:

  • 默认启动

  • 指定配置启动

  • 开机自启

1.默认启动

安装完成后,在任意目录输入redis-server命令即可启动Redis:

redis-server

如图:

这种启动属于前台启动,会阻塞整个会话窗口,窗口关闭或者按下CTRL + C则Redis停止。不推荐使用。

2.指定配置启动

如果要让Redis以后台方式启动,则必须修改Redis配置文件,就在我们之前解压的redis安装包下(/usr/local/redis-6.2.6),名字叫redis.conf:

我们先将这个配置文件备份一份:

cp redis.conf redis.conf.bak

然后修改redis.conf文件中的一些配置:

# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes 
# 密码,设置后访问Redis必须输入密码
requirepass 123321

Redis的其它常见配置:

# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"

启动Redis:

# 进入redis安装目录 
cd /usr/local/bin
# 启动
./redis-server /usr/local/redis-6.2.6/redis.conf

3.开机自启

我们也可以通过配置来实现开机自启。

首先,新建一个系统服务文件:

vi /etc/systemd/system/redis.service

内容如下:

[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/redis-6.2.6/redis.conf
PrivateTmp=true

[Install]
WantedBy=multi-user.target

然后重载系统服务:

systemctl daemon-reload

现在,我们可以用下面这组命令来操作redis了:

# 启动
service redis start 
# 停止
service redis stop
# 重启
service redis restart
# 查看状态
service redis  status

执行下面的命令,可以让redis开机自启:

systemctl enable redis

三、 Redis数据库相关指令

1 数据库操作指令

# 1.Redis中库说明
- 使用redis的默认配置器动redis服务后,默认会存在16个库,编号从0-15
- 可以使用select 库的编号 来选择一个redis的库

# 2.Redis中操作库的指令
- 清空当前的库  FLUSHDB
- 清空全部的库  FLUSHALL

# 3.redis客户端显示中文
-	./redis-cli  -p 7000 --raw

2 操作key相关指令

# 1.DEL指令
- 语法 :  DEL key [key ...] 
- 作用 :  删除给定的一个或多个key 。不存在的key 会被忽略。
- 可用版本: >= 1.0.0
- 返回值: 被删除key 的数量。 

# 2.EXISTS指令
- 语法:  EXISTS key
- 作用:  检查给定key 是否存在。
- 可用版本: >= 1.0.0
- 返回值: 若key 存在,返回1 ,否则返回0。

# 3.EXPIRE
- 语法:  EXPIRE key seconds
- 作用:  为给定key 设置生存时间,当key 过期时(生存时间为0 ),它会被自动删除。
- 可用版本: >= 1.0.0
- 时间复杂度: O(1)
- 返回值:设置成功返回1 。

# 4.KEYS
- 语法 :  KEYS pattern
- 作用 :  查找所有符合给定模式pattern 的key 。
- 语法:
	KEYS * 匹配数据库中所有key 。
	KEYS h?llo 匹配hello ,hallo 和hxllo 等。
	KEYS h*llo 匹配hllo 和heeeeello 等。
	KEYS h[ae]llo 匹配hello 和hallo ,但不匹配hillo 。特殊符号用 "\" 隔开
- 可用版本: >= 1.0.0
- 返回值: 符合给定模式的key 列表。

# 5.TTL
- 语法 :   TTL key
- 作用 :   以秒为单位,返回给定key 的剩余生存时间(TTL, time to live)。
- 可用版本: >= 1.0.0
- 返回值:
	当key 不存在时,返回-2 。
	当key 存在但没有设置剩余生存时间时,返回-1 。
	否则,以秒为单位,返回key 的剩余生存时间。
- Note : 在Redis 2.8 以前,当key 不存在,或者key 没有设置剩余生存时间时,命令都返回-1 。

# 6.RENAME
- 语法 :  RENAME key newkey
- 作用 :  将key 改名为newkey 。当key 和newkey 相同,或者key 不存在时,返回一个错误。当newkey 已经存在时,RENAME 命令将覆盖旧值。
- 可用版本: >= 1.0.0
- 返回值: 改名成功时提示OK ,失败时候返回一个错误。

# 7.TYPE
- 语法 :  TYPE key
- 作用 :  返回key 所储存的值的类型。
- 可用版本: >= 1.0.0
- 返回值:
	none (key 不存在)
	string (字符串)
	list (列表)
	set (集合)
	zset (有序集)
	hash (哈希表)

Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样:官网也给出了命令解释

redis在存储数据的时候是以键值对存在的

key一般是String类型

不过value的类型多种多样,

redis的五种基本数据类型,指的就是value的类型

Commands | Redis

3 String类型

1. 内存存储模型

2. 常用操作命令
命令说明
set设置一个key/value
get根据key获得对应的value
mset一次设置多个key value
mget一次获得多个key的value
getset获得原始key的值,同时设置新值
strlen获得对应key存储value的长度
append为对应key的value追加内容
setex设置一个key存活的有效期(秒)
setnx存在不做任何操作,不存在添加
msetnx原子操作(只要有一个存在不做任何操作)可以同时设置多个key,只有有一个存在都不保存
decr进行数值类型的-1操作
decrby根据提供的数据进行减法操作
Incr进行数值类型的+1操作
incrby根据提供的数据进行加法操作

incrby age 10

setex key time value

4 List类型

list 列表 相当于java中list 集合 特点 元素有序 且 可以重复

1.内存存储模型

2.常用操作指令
命令说明
lpush将某个值加入到一个key列表头部
lpushx同lpush,但是必须要保证这个key存在
rpush将某个值加入到一个key列表末尾
rpushx同rpush,但是必须要保证这个key存在
lpop返回和移除列表左边的第一个元素
rpop返回和移除列表右边的第一个元素
lrange获取某一个下标区间内的元素,从0开始
llen获取列表元素个数
lset设置某一个指定索引的值(索引必须存在)
lindex获取某一个指定索引位置的元素
lrem删除重复元素
ltrim保留列表中特定区间内的元素
linsert在某一个元素之前,之后插入新元素

lpush 集合名 元素名

llen 集合名

lrange 集合名 开始索引 结束索引

lindex 集合名 索引

lrem 集合名 删除的个数 元素名

5 Set类型

特点: Set类型 Set集合 元素无序 不可以重复,好友,可能认识的人。

1.内存存储模型

2.常用命令
命令说明
sadd为集合添加元素
smembers显示集合中所有元素 无序
scard返回集合中元素的个数
spop随机返回一个元素 并将元素在集合中删除
smove从一个集合中向另一个集合移动元素 必须是同一种类型
srem从集合中删除一个元素
sismember判断一个集合中是否含有这个元素
srandmember随机返回元素
sdiff求差集
sinter求交集
sunion求和集

sadd 集合名 元素名

smembers 集合名

scard 集合名

sinter 集合1 集合2

6 ZSet类型

特点: 可排序的set集合 排序 不可重复 ,因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。底层的实现是一个跳表(SkipList)加 hash表。

ZSET 官方 可排序SET sortSet

1.内存模型

2.常用命令
命令说明
zadd添加一个有序集合元素
zcard返回集合的元素个数
zrange 升序 zrevrange 降序返回一个范围内的元素
zrangebyscore按照分数查找一个范围内的元素
zrank返回排名
zrevrank倒序排名
zscore显示某一个元素的分数
zrem移除某一个元素
zincrby给某个特定元素加分
ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN
zrange 集合名 开始索引  结束索引

7 hash类型

特点: value 是一个map结构 存在key value key 无序的

1.内存模型

2.常用命令
命令说明
hset设置一个key/value对
hget获得一个key对应的value
hgetall获得所有的key/value对
hdel删除某一个key/value对
hexists判断一个key是否存在
hkeys获得所有的key
hvals获得所有的value
hmset设置多个key/value
hmget获得多个key的value
hsetnx设置一个不存在的key的值
hincrby为value进行加法运算
hincrbyfloat为value加入浮点值

hset 集合名 key value hset key key value

hset 集合 key

四、持久化机制

client redis[内存] -----> 内存数据- 数据持久化-->磁盘

Redis官方提供了两种不同的持久化方法来将数据存储到硬盘里面分别是:

  • RDB 快照(Snapshot)

  • AOF (Append Only File) 只追加日志文件

1 快照(Snapshot)

1. 特点

这种方式可以将某一时刻的所有数据都写入硬盘中,当然这也是redis的默认开启持久化方式,保存的文件是以.rdb形式结尾的文件因此这种方式也称之为RDB方式。

2.快照生成方式
  • 客户端方式: BGSAVE 和 SAVE指令

  • 服务器配置自动触发

# 1.客户端方式之BGSAVE
- a.客户端可以使用BGSAVE命令来创建一个快照,当接收到客户端的BGSAVE命令时,redis会调用fork来创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求。
	
	名词解释: fork当一个进程创建子进程的时候,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化:在刚开始的时候,父子进程共享相同内存,直到父进程或子进程对内存进行了写之后,对被写入的内存的共享才会结束服务`

# 2.客户端方式之SAVE
- b.客户端还可以使用SAVE命令来创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令

  • 注意: SAVE命令并不常用,使用SAVE命令在快照创建完毕之前,redis处于阻塞状态,无法对外服务

# 3.服务器配置方式之满足配置自动触发
- 如果用户在redis.conf中设置了save配置选项,redis会在save选项条件满足之后自动触发一次BGSAVE命令,如果设置多个save配置选项,当任意一个save配置选项条件满足,redis也会触发一次BGSAVE命令

# 4.服务器接收客户端shutdown指令
- 当redis通过shutdown指令接收到关闭服务器的请求时,会执行一个save命令,阻塞所有的客户端,不再执行客户端执行发送的任何命令,并且在save命令执行完毕之后关闭服务器
3.配置生成快照名称和位置
#1.修改生成快照名称
- dbfilename dump.rdb

# 2.修改生成位置
- dir ./


2 AOF 只追加日志文件

1.特点

这种方式可以将所有客户端执行的写命令记录到日志文件中,AOF持久化会将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化,因此只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集.

2.开启AOF持久化

在redis的默认配置中AOF持久化机制是没有开启的,需要在配置中开启

# 1.开启AOF持久化
- a.修改 appendonly yes 开启持久化
- b.修改 appendfilename "appendonly.aof" 指定生成文件名称

3.日志追加频率
# 1.always 【谨慎使用】
- 说明: 每个redis写命令都要同步写入硬盘,严重降低redis速度
- 解释: 如果用户使用了always选项,那么每个redis写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减到最少;遗憾的是,因为这种同步策略需要对硬盘进行大量的写入操作,所以redis处理命令的速度会受到硬盘性能的限制;
- 注意: 转盘式硬盘在这种频率下200左右个命令/s ; 固态硬盘(SSD) 几百万个命令/s;
- 警告: 使用SSD用户请谨慎使用always选项,这种模式不断写入少量数据的做法有可能会引发严重的写入放大问题,导致将固态硬盘的寿命从原来的几年降低为几个月。

# 2.everysec 【推荐】
- 说明: 每秒执行一次同步显式的将多个写命令同步到磁盘
- 解释: 为了兼顾数据安全和写入性能,用户可以考虑使用everysec选项,让redis每秒一次的频率对AOF文件进行同步;redis每秒同步一次AOF文件时性能和不使用任何持久化特性时的性能相差无几,而通过每秒同步一次AOF文件,redis可以保证,即使系统崩溃,用户最多丢失一秒之内产生的数据。

# 3.no	【不推荐】
- 说明: 由操作系统决定何时同步 
- 解释:最后使用no选项,将完全有操作系统决定什么时候同步AOF日志文件,这个选项不会对redis性能带来影响但是系统崩溃时,会丢失不定数量的数据,另外如果用户硬盘处理写入操作不够快的话,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,并导致redis的处理命令请求的速度变慢。
4.修改同步频率
# 1.修改日志同步频率
- 修改appendfsync everysec|always|no 指定


3 AOF文件的重写

1. AOF带来的问题

AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件Redis提供了AOF重写(ReWriter)机制。

2. AOF重写

用来在一定程度上减小AOF文件的体积

3. 触发重写方式
# 1.客户端方式触发重写
- 执行BGREWRITEAOF命令  不会阻塞redis的服务

# 2.服务器配置方式自动触发
- 配置redis.conf中的auto-aof-rewrite-percentage选项 参加下图↓↓↓
- 如果设置auto-aof-rewrite-percentage值为100和auto-aof-rewrite-min-size 64mb,并且启用的AOF持久化时,那么当AOF文件体积大于64M,并且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,用户可以考虑将auto-aof-rewrite-percentage设置为更大

4. 重写原理

注意:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,替换原有的文件这点和快照有点类似。

# 重写流程
- 1. redis调用fork ,现在有父子两个进程 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
- 2. 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
- 3. 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
- 4. 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。


4 持久化总结

两种持久化方案既可以同时使用(aof),又可以单独使用,在某种情况下也可以都不使用,具体使用那种持久化方案取决于用户的数据和应用决定。

无论使用AOF还是快照机制持久化,将数据持久化到硬盘都是有必要的,除了持久化外,用户还应该对持久化的文件进行备份(最好备份在多个不同地方)。


五 SpringBoot整合Redis

Spring Boot Data(数据) Redis 中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子类,两个方法基本一致,不同之处主要体现在操作的数据类型不同,RedisTemplate中的两个泛型都是Object,意味着存储的key和value都可以是一个对象,而StringRedisTemplate的两个泛型都是String,意味着StringRedisTemplate的key和value都只能是字符串。

注意: 使用RedisTemplate默认是将对象序列化到Redis中,所以放入的对象必须实现对象序列化接口

1.引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- spring2.X集成redis所需common-pool2-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2.配置application.propertie

#Redis服务器地址
spring.redis.host=192.168.56.130
#Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123321
#Redis数据库索引(默认为0)
spring.redis.database= 0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0

pom.xml修改打包插件

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.7</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.shared</groupId>
                        <artifactId>maven-filtering</artifactId>
                        <version>1.3</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>

使用RedisTemplate

@SpringBootTest
class RedisdemoApplicationTests {

     @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Test
    void testList() {
        redisTemplate.opsForValue().set("name","张三");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);
    }
}

控制台输出没有问题,但是软件中显示乱码了

所以我们需要配置redis的序列化

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 创建Template
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // key和 hashKey采用 string序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value和 hashValue采用 JSON序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        return redisTemplate;
    }
    

RedisTemplate封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

3 使用RedisTemplate

1 opsForValue

  @Test
    void testString() {
        redisTemplate.opsForValue().set("name","张三");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println(name);
    }

2 opsForHash

@Test
    void testHash() {
        redisTemplate.opsForHash().put("person","name","老韩");
        Object name = redisTemplate.opsForHash().get("person", "name");
        System.out.println(name);
    }

3 opsForSet

@Test
    void testSet(){
        redisTemplate.opsForSet().add("myFriend", "郝翊", "赵逸凡", "耿梦婷", "索伟", "谭智尤");
        redisTemplate.opsForSet().add("yourFriend", "郝翊", "武锦龙", "李明生", "索伟", "谭智尤");
        Set<Object> myFriend = redisTemplate.opsForSet().members("myFriend");
        Set<Object> difference = redisTemplate.opsForSet().difference( "yourFriend","myFriend");
        Set<Object> intersect = redisTemplate.opsForSet().intersect("myFriend", "yourFriend");
        System.out.println("我的好友:"+myFriend);
        System.out.println("你可能也认识:"+difference);
        System.out.println("你两共同的好友:"+intersect);
    }

4 opsForZSet

@Test
    void testZset(){
        redisTemplate.opsForZSet().add("leaderboard", "厨子哥",100);
        redisTemplate.opsForZSet().add("leaderboard", "张震",70);
        redisTemplate.opsForZSet().add("leaderboard", "冯杰",90);
        redisTemplate.opsForZSet().add("leaderboard", "曹璟昊",55);
        Set<Object> leaderboard = redisTemplate.opsForZSet().range("leaderboard", 0, -1);
        Long num = redisTemplate.opsForZSet().zCard("leaderboard");
        Set<Object> leaderboard1 = redisTemplate.opsForZSet().reverseRange("leaderboard", 0, -1);
        redisTemplate.opsForZSet().incrementScore("leaderboard", "曹璟昊", 50);
        Set<Object> leaderboard2 = redisTemplate.opsForZSet().reverseRange("leaderboard", 0, -1);
        System.out.println("参与选美的选手有:"+leaderboard+","+num+"个人");
        System.out.println("倒排:"+leaderboard1);
        System.out.println("加分后倒排:"+leaderboard2);
    }

5 opsForList

@Test
    void testList(){
        redisTemplate.opsForList().leftPush("lists", "苹果");
        redisTemplate.opsForList().leftPushAll("lists", "香蕉","哈密瓜");
        List<Object> lists = redisTemplate.opsForList().range("lists", 0, -1);
        lists.forEach(s-> System.out.println(s));
    }

6 key操作

 @Test
    void testKey(){
        Set<String> keys = redisTemplate.keys("*");
        System.out.println(keys);
        Boolean nameExist = redisTemplate.hasKey("myFriend");
        System.out.println(nameExist);
        Boolean del = redisTemplate.delete("myFriend");
        System.out.println(del);
        redisTemplate.rename("lists","list11");
        redisTemplate.expire("list11", 5, TimeUnit.MINUTES);
        keys = redisTemplate.keys("*");
        System.out.println(keys);

    }

7 工具类

在工作中如果经常操作redis我们可以将redis封装到工具类里,导入项目里面直接使用

七、 Redis 主从复制

1 主从复制

主从复制架构仅仅用来解决数据的冗余备份,从节点仅仅用来同步数据

无法解决: 1.master节点出现故障的自动故障转移

2 主从复制架构图

3 搭建主从复制

service network restart

vi /usr/local/redis-6.2.6/redis.conf

# 1.准备3台机器并修改配置
- master
	port 6379
	bind 0.0.0.0
	
- slave1
	port 6379
	bind 0.0.0.0
	slaveof masterip masterport
	slaveof 192.168.56.171 6379

- slave2
	port 6379
	bind 0.0.0.0
	slaveof 192.168.56.171 6379


# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes 
# 密码,设置后访问Redis必须输入密码
requirepass 123321
	
bind 0.0.0.0
port 6379
daemonize yes
requirepass 123321





bind 0.0.0.0
port 6379
daemonize yes
replicaof 192.168.32.11 6379	
masterauth 123321
slaveof 192.168.32.11 6379
requirepass 123321



bind 0.0.0.0
port 6379
daemonize yes
replicaof 192.168.32.11 6379	
masterauth 123321
slaveof 192.168.32.11 6379
requirepass 123321

# 2.启动3台机器进行测试
- cd /usr/redis/bin
- ./redis-server /root/master/redis.conf
- ./redis-server /root/slave1/redis.conf
- ./redis-server /root/slave2/redis.conf

查看集群信息: info replication

八、Redis哨兵机制

1 哨兵Sentinel机制

Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。简单的说哨兵就是带有自动故障转移功能的主从架构

无法解决: 1.单节点并发压力问题 2.单节点内存和磁盘物理上限

2 哨兵架构原理

3 搭建哨兵架构

# 1.在主节点上创建哨兵配置
- 在Master对应redis.conf同目录下新建sentinel.conf文件,名字绝对不能错;

# 2.配置哨兵,在sentinel.conf文件中填入内容:
- sentinel monitor 被监控数据库名字(自己起名字) ip port 2
sentinel monitor mymaster 192.168.32.11 6379 1
sentinel auth-pass mymaster 123321

# 3.启动哨兵模式进行测试
./redis-sentinel  /usr/local/redis-6.2.6/sentinel.conf 

说明:这个后面的数字2,是指当有两个及以上的sentinel服务检测到master宕机,才会去执行主从切换的功能。

id 越小 优先权越大

偏移量越大,优先权越高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/317118.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML--图片

HTML中使用 img标签来显示一张图片 它有三个属性&#xff1a; src alt tiltle src属性&#xff1a; 图片路径建议为相对路径&#xff0c;以免文件移动造成无法正常工作 用法&#xff1a; <img src"图片路径和名字"><!DOCTYPE html> <html> <…

【数据库】sql优化有哪些?从query层面和数据库层面分析

目录 归纳sql本身的优化数据库层面的优化 归纳 这类型问题可以称为&#xff1a;Query Optimization&#xff0c;从清华AI4DB的paper list中&#xff0c;该类问题大致可以分为&#xff1a; Query RewriterCardinality EstimationCost EstimationPlan Optimization 从中文的角…

20240110在ubuntu20.04下重启samba服务

20240110在ubuntu20.04下重启samba服务 百度搜索&#xff1a;samba restart https://www.python100.com/html/78028.html 重启samba命令详解 更新&#xff1a;2023-05-17 16:04 一、重启samba命令 重启samba可以使用以下命令&#xff1a; /etc/init.d/smb restart 或者 syste…

debian12部署Gitea服务之二——部署git-lfs

Debian安装gitlfs: 先更新下软件包版本 sudo apt update 安装 sudo apt install git-lfs 验证是否安装成功 git lfs version cd到Gitea仓库目录下 cd /mnt/HuHDD/Git/Gitea/Repo/hu/testrepo.git 执行lfs的初始化命令 git lfs install客户机Windows端在官网下载并安装Git-Lfs 再…

基于kkFileView实现万能文件预览

基于kkFileView实现万能文件预览 1.简介 文档在线预览项目解决方案&#xff0c;项目使用流行的spring boot搭建&#xff0c;易上手和部署。万能的文件预览开源项目&#xff0c;基本支持主流文档格式预览 官网&#xff1a;https://kkview.cn/zh-cn/docs/home.html github地址…

sectigo dv证书适合场景买一年送一月

Sectigo是成立于美国的知名CA认证机构&#xff0c;随着互联网的发展&#xff0c;Sectigo颁发了越来越多的SSL数字证书。这些SSL证书产品不仅可以对网站传输数据进行加密服务&#xff0c;还可以对服务器身份进行认证服务。Sectigo旗下的DV证书产品比较齐全&#xff0c;适用场景也…

【动态规划】【记忆化搜索】C++算法:546移除盒子

作者推荐 【动态规划】458:可怜的小猪 本文涉及知识点 动态规划 记忆化搜索 LeetCode546. 移除盒子 给出一些不同颜色的盒子 boxes &#xff0c;盒子的颜色由不同的正数表示。 你将经过若干轮操作去去掉盒子&#xff0c;直到所有的盒子都去掉为止。每一轮你可以移除具有相…

[C++]多态

目录 C多态&#xff1a;&#xff1a; 多态的概念 多态的定义及实现 多态的构成条件 虚函数 虚函数的重写 虚函数重写的特例 C11 override和final 重载、重写重定义的对比 抽象类 概念 接口继承和实现继承 多态的原理 虚函数表 多态的原理 动态绑定和静态绑定 单继承和…

智能分析网关V4:搭建智慧幼儿园视频AI智能监管方案

一、背景需求 随着科技的日新月异&#xff0c;智慧化监管在幼儿园管理领域的应用已成为不可逆转的趋势。在传统的幼儿园管理模式中&#xff0c;校园安全管理往往依赖于人工查看监控&#xff0c;难以及时发现安全隐患。智慧幼儿园监管解决方案通过引入物联网、大数据、人工智能…

C# IOC 容器实战:KeyedService和生命周期

文章目录 前言KeyedServiceKey缺少Key值覆盖 KeyedService.AnyKey生命周期测试代码 总结 前言 我之前写过一篇Ioc容器的使用&#xff0c;用的是微软的IOC容器。这次我们再去深入了解一下IOC 和控制反转 .NET Core 依赖注入 Microsoft.Extensions.DependencyInjection ASP.NET …

josef约瑟 中间继电器 HJDZ-E440额定电压:AC220V 卡轨安装

HJDZ-静态中间继电器 系列型号&#xff1a; HJDZ-A200静态中间继电器&#xff1b;HJDZ-A110静态中间继电器&#xff1b; HJDZ-A002静态中间继电器&#xff1b;HJDZ-A004静态中间继电器&#xff1b; HJDZ-E112静态中间继电器&#xff1b;HJDZ-E112L静态中间继电器&#xff1…

数据结构入门到入土——栈(Stack)和队列(Queue)

目录 一&#xff0c;栈&#xff08;Stack&#xff09; 1.1 概念 1.2 栈的使用 1.3 栈的模拟实现 1.4 栈的应用场景 1.5 栈&#xff0c;虚拟机栈&#xff0c;栈帧有什么区别&#xff1f; 二&#xff0c;队列&#xff08;Queue&#xff09; 2.1 概念 2.2 队列的使用 2.3 …

luceda ipkiss教程 55:画螺旋型布拉格光栅

案例分享, 画螺旋型布拉格光栅: 所有代码如下&#xff1a; from si_fab import all as pdk import ipkiss3.all as i3 from picazzo3.wg.spirals import FixedLengthSpiralRoundedgrating_size 0.7 grating_wg_width 1.2 wg_width 0.5 pitch 1.4 reference i3.LayoutCel…

【HuggingFace Transformer库学习笔记】基础组件学习:Datasets

基础组件——Datasets datasets基本使用 导入包 from datasets import *加载数据 datasets load_dataset("madao33/new-title-chinese") datasetsDatasetDict({train: Dataset({features: [title, content],num_rows: 5850})validation: Dataset({features: [titl…

【Web】NSSCTF Round#16 Basic个人wp(全)

出题友好&#xff0c;适合手生复健。 目录 ①RCE但是没有完全RCE ②了解过PHP特性吗 ①RCE但是没有完全RCE 上来就是一段md5八股 (string)就是不让用数组了&#xff0c;然后强比较需要md5碰撞 ?md5_1%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc…

KVM Vcpu概述

KVM Vcpu概述 Intel VTSMP系统CPU过载使用CPU模型CPU绑定和亲和性CPU优化 Intel VT Intel的硬件虚拟化技术大致分为3类&#xff1a; 1、VT-x技术&#xff1a;是指Intel处理器中的一些虚拟化技术支持&#xff0c;包括CPU中最基础的VMX技术&#xff0c;也包括内存虚拟化的硬件支…

【LangChain学习之旅】—(7) 调用模型:使用OpenAI API还是微调开源Llama2/ChatGLM?

【LangChain学习之旅】—&#xff08;7&#xff09; 调用模型&#xff1a;使用OpenAI API还是微调开源Llama2/ChatGLM&#xff1f; 大语言模型发展史预训练 微调的模式用 HuggingFace 跑开源模型申请使用 Meta 的 Llama2 模型通过 HuggingFace 调用 LlamaLangChain 和 Hugging…

PHP代码审计基础知识

前言 本文章主要是PHP代码审计的一些基础知识&#xff0c;包括函数的用法&#xff0c;漏洞点&#xff0c;偏向基础部分&#xff0c;个人能力有限&#xff0c;部分可能会出现错误或者遗漏&#xff0c;读者可自行补充。 代码执行 代码执行是代码审计当中较为严重的漏洞&…

关于LwRB环形缓冲区开源库的纯C++版本支持原子操作

1、LwRB环形缓冲区开源库&#xff1a; GitHub - MaJerle/lwrb: Lightweight generic ring buffer manager libraryLightweight generic ring buffer manager library. Contribute to MaJerle/lwrb development by creating an account on GitHub.https://github.com/MaJerle/l…

【Linux】Linux基础之权限

目录 一、Linux中的用户1.1 用户之间的身份切换1.2 指令提权 二、权限管理2.1 文件权限2.2 权限操作2.3 chown和chgrp 三、文件类型四、目录文件的权限操作五、权限掩码六、粘滞位 一、Linux中的用户 Linux中主要有两种用户&#xff1a; root&#xff0c;超级用户非root&…