banner
NEWS LETTER

Redis缓存数据库

Scroll down

Redis数据库

什么是Redis?

Redis是一种基于内存的key-value结构数据库

他会将我们的数据存放在内存中,这就有利于提高获取数据的速度。同时因为它是存放在内存中,所以当服务器断电时里面的数据也会不复存在

Redis简介

  • Redis是一个开源的内存中的数据结构存储系统,他可以用作:数据库、缓存和消息中间件

  • 官网:https://redis.io

  • Redis是用C语言开发的一个开源的高性能键值对(key-value

数据库,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的nosql数据库

  • Nosql,泛指非关系型数据库

Redis下载与安装

windows系统

将下载好的.zip格式压缩包,直接解压就可以直接使用

image-20230412110246114

linux系统

  1. 将Redis安装包上传到linux
  2. 解压安装包,命令:tar -zxvf redis-4.0.0.tar.gz -C /usr/local
  3. 安装redis的依赖环境gcc,命令:yum install gcc-c++
  4. 进入/usr/local/redis-4.0.0,进行编译,命令:make
  5. 进入redis的src目录,进行安装,命令:make install

Redis启动

linux启动

redis-4.0.0 -> src文件夹下执行:./redis-server

设置后台运行:

  1. redis-4.0.0下运行vim redis.conf

  2. 输入dae将检索到的no改为yes

  3. 保存退出

  4. 运行./redis-server ./redis.conf

使用命令

src下./redis-cli

windows启动

运行redis-server.exe

Redis设置密码

  1. 在radis.conf中检索password,将注释解掉,并把第二个单词改成需要的密码
  2. 保存,重启服务
  3. 输入src/redis-cli回车
  4. 输入auth 你的密码

设置允许远程连接

  1. 在radis.conf中检索bind
  2. 将bind 127.0.0.1注释掉
  3. 重启服务
  4. 在windows中的radis路径中使用powershell运行命令:

.\redis-cli.exe -h 192.168.136.131 -p 6379 -a 510609

Redis数据类型

Redis存储的是key-value结构的数据,其中key是字符串类型,value有五种常用的数据类型

  • 字符串string类型:string普通字符串,常用
  • 哈希表hash类型:hash适合存储对象
  • 列表list类型:list按照插入顺序排列,允许存在重复的元素
  • 无序集合set类型:set无序集合,没有重复的元素
  • 有序集合sorted set类型:有序集合,没有重复元素

Redis常用命令

字符串String操作命令

1
2
3
4
5
6
7
8
9
10
11
#设置key和对应的value
set key value

#获取key对应的value值
get key

#设置key存在的秒数
setex key seconds value

#只有在key不存在时设置key的值
setnx key value

哈希hash操作命令

Redis hash是一个string类型的field和calue的映射表,hash特别适合用于存储对象,常用的命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#使用 HSET 添加一个字段和值到哈希表中:
HSET myhash field1 "Hello"
#这将在名为 myhash 的哈希表中添加一个字段 field1 并将其值设置为 "Hello"。

#使用 HGET 获取哈希表中指定字段的值:
HGET myhash field1
#这将返回名为 myhash 的哈希表中 field1 字段的值。

#使用 HMSET 添加多个字段和值到哈希表中:
HMSET myhash field1 "Hello" field2 "World"
#这将在名为 myhash 的哈希表中添加两个字段 field1 和 field2 并将它们的值设置为 "Hello" 和 "World"。

#使用 HLEN 获取哈希表中字段的数量:
HLEN myhash
#这将返回名为 myhash 的哈希表中字段的数量。

#使用 HEXISTS 检查哈希表中是否存在指定的字段:
HEXISTS myhash field1
#这将返回一个布尔值,表示名为 myhash 的哈希表中是否存在 field1 字段。

#使用 HDEL 删除哈希表中的一个或多个字段:
HDEL myhash field1 field2
#这将从名为 myhash 的哈希表中删除 field1 和 field2 两个字段。

#使用 HKEYS 获取名为 myhash 的哈希表中的所有字段名:
HKEYS myhash
#这将返回一个数组,包含名为 myhash 的哈希表中的所有字段名。

#使用 HVALS 获取名为 myhash 的哈希表中的所有字段值:
HVALS myhash
#这将返回一个数组,包含名为 myhash 的哈希表中的所有字段值。

列表list操作命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#将一个或多个值插入到列表头部,返回列表的长度
LPUSH mylist "hello"

#移除并返回移除的头部元素
LPOP mylist

#移除并返回移除的尾部元素
RPOP mylist

#获取列表指定范围内的所有元素(返回一个数组)
LRANGE mylist 0 1

#查询指定列表所有的数据
LRANGE mylist 0 -1

#获取列表指定索引位置的元素,返回指定位置的元素
LINDEX mylist 0

#获取列表的长度
LLEN mylist

#修改指定索引位置的数据
LSET mylist 1 orange

无序集合set操作命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#向集合添加一个或多个成员
SADD myset apple
SADD myset orange banana

#从集合中删除一个或多个成员
SREM myset orange

#返回集合中所有的成员
SMEMBERS myset

#返回集合的基数(集合中元素的数量)
SCARD myset

#判断一个元素是否是集合的成员
SISMEMBER myset apple

#返回所有给定集合的并集
SUNION set1 set2

#返回所有给定集合的差集
SDIFF set1 set2

#返回所有给定集合的交集
SINTER set1 set2

有序集合sorted set操作命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#向有序集合中添加成员
ZADD myset 20 "Bob" 30 "Charlie"

#获取成员的分数
ZSCORE myset "Alice"

#移除成员
ZREM myset "Bob"

#增加成员的分数
ZINCRBY myset 5 "Charlie"
#35

#获取成员的排名
#从大到小
ZRANK myset "Alice"
#从小到大
ZREVRANK myset "Charlie"

#获取指定范围内的成员列表
> ZRANGEBYSCORE myset 10 30 WITHSCORES LIMIT 0 2
1) "Alice"
2) "10"
3) "Charlie"
4) "30"
#通过执行ZRANGEBYSCORE指令获取了myset有序集合中分数在10到30之间(包括10和30)的两个成员。由于指定了WITHSCORES选项,因此返回结果中包含每个成员的分数值。同时,由于指定了LIMIT选项,因此结果集合数量被限制为2个,并且偏移量为0。

通用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
KEYs pattern
#查找所有符合给定模式( pattern)的 key

EXISTs key
#检查给定key是否存在

rYPE key
#返回key所储存的值的类型

TTL key
#返回给定key 的剩余生存时间(TTL, time to live),以秒为单位

DEL key
#该命令用于在 key存在是删除key

Java操作radis

Java设置radis的spring类型

1
2
3
4
5
6
7
8
9
10
11
/*添加键值对*/
redisTemplate.opsForValue().set("city","beijing");

/*获取数据*/
String value = (String) redisTemplate.opsForValue().get("city");

/*添加键值对并设置过期时间101秒*/
redisTemplate.opsForValue().set("city","beijing",101, TimeUnit.SECONDS);

/*设置如果则不执行,如果没有就加上*/
Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("city", "nanjing");

Java设置radis的list类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ListOperations listOperations = redisTemplate.opsForList();

/*向list中存入多个值*/
listOperations.leftPushAll("mylist","b","c","d");

/*取值*/
List<String> mylist = listOperations.range("mylist", 0, -1);
for (String value : mylist) {
System.out.println(value);
} /*输出dcba*/

/*获得列表长度llen*/
Long size=listOperations.size("mylist");
int lsize = size.intValue();
for (int i = 0; i < lsize; i++) {
/*出队列*/
Object element = listOperations.rightPop("mylist");
System.out.println((String)element);
}

Java设置radis的hash类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
HashOperations hashOperations=redisTemplate.opsForHash();

/*存值*/
hashOperations.put("002","name","xiaoming");
hashOperations.put("002","age","20");
hashOperations.put("002","address","bj");

/*取值*/
String age=(String) hashOperations.get("002","age");
System.out.println(age);

/*获得hash结构中所有字段*/
set keys=hashOperations.keys("002");
for (Object key : keys) {
System.out.println(key);
}

/*获得hash结构中所有字段*/
List values=hashOperations.values("002");
for (Object value : values) {
System.out.println(value);
}

Java设置radis的Set类型

1
2
3
4
5
6
7
8
9
10
11
12
13
SetOperations setOperations= redisTemplate.opsForSet();

/*存值*/
setOperations.add("myset","a","b","c","a");

/*取值*/
Set<String> myset=setOperations.members("myset");
for (String o:myset){
System.out.println(o);
}

/*删除成员*/
setOperations.remove("myset","b","a");

Java设置radis的sorted set类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ZSetOperations zSetOperations=redisTemplate.opsForZSet();

/*存值*/
zSetOperations.add("myzset","a",10.0);
zSetOperations.add("myzset","b",20.0);
zSetOperations.add("myzset","c",30.0);
zSetOperations.add("myzset","d",40.0);

/*取值*/
Set<String> myzset= zSetOperations.range("myzset",0,-1);
for(String s:myzset){
System.out.println(s);
}

/*修改分数,添加20*/
zSetOperations.incrementScore("myzset","b",20.0);

/*删除*/
zSetOperations.remove("myzset","a","b");

使用Spring Sache

Spring Cache简介

Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。

Spring Cache提供了一层抽象,底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。

针对不同的缓存技术需要实现不同的CacheManager

CacheManager 描述
EhCacheCacheManager 使用EhCache作为缓存技术
GuavaCacheManager 使用Google的GuavaCache作为缓存技术
RedisCacheManager 使用Redis作为缓存技术

Spring Cache常用注解

注解 说明
@EnableCaching 开启缓存注解功能
@Cacheable 在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
@CachePut 将方法的返回值放到缓存中
@CacheEvict 将一条或多条数据从缓存中删除

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Cacheable:查询指定缓存,在执行时先查看缓存中是否有数据。如果有,优先加载内存。如果没有再去mysql中查找
* value:缓存的名称,每个缓存名称下面可以有多个key
* key:缓存的key
* condition:满足条件时才会缓存数据
* @param id
*/
@Cacheable(value = "userCache", key = "#id",condition = "#id != null")
@GetMapping("/{id}")
public User getById(@PathVariable Long id){
User user = userService.getById(id);
return user;
}

Redis主从复制

首先本机设为从库,服务器作为主库


修改服务器(主库)

打开 Redis 主服务器 redis.windows.conf 配置文件,找到 bind 和 port 配置项,确保 Redis 绑定的 IP 地址和端口号正确:

1
2
3
bind 127.0.0.1 		# 这里改成服务器的 IP 地址或者绑定的外网地址
port 6379 # 这里保持默认的 Redis 端口号
requirepass 510609 # 设置主库密码

主库src中运行:

1
2
3
redis-server ../redis.conf						#运行服务
redis-cli -h 192.168.136.131 -p 6379 -a 510609 #设置当前主库ip、端口和密码
info replication #查看角色和状态

修改本机(从库)

打开redis.conf配置文件

1
2
slaveof 192.168.56.110 6379		#配置所属主服务器的ip和端口号
masterauth 510609 #配置所属主服务的密码

从库中启动redis-server.exe和redis-cli.exe,并运行

1
2
3
slaveof 192.168.136.131 6379	#设置所属主库ip和端口号
config set masterauth 510609 #填写主库密码
info replication #查看角色和状态

redis哨兵机制

主从复制带来的问题

当主服务宕机时,redis不能自动切换从服务为主服务,只能通过人工手动的形式,中间会出现服务断档

从而引入哨兵模式概念:

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

用文字描述一下故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。

哨兵配置

  1. 在readis文件夹下找到sentinel.conf文件

  2. 修改对应配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #禁止保护配置
    protected-mode no

    #监控配置
    #setinel monitor:代表监控;
    #mymaster:代表主机名,可以自定义;
    #192.168.56.110∶主服务ip地址;
    #6379∶主服务端口号;
    #2:需要几个哨兵意见统一
    sentinel monitor mymaster 192.168.56.110 6379 2

    #配置后台启动
    daemonize yes
  3. 启动哨兵

    Sentinel ./sentinel.conf

Other Articles
cover
HTML精讲
  • 23/09/18
  • 18:15
  • 3.1k
  • 13
cover
SpringBoot笔记
  • 23/06/12
  • 20:17
  • 1.3k
  • 6