Redis学习笔记

cnbigmx 萌新

Redis

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

  • 基于内存存储,读写性能高
  • 适合存储热点数据(热点商品,资讯、新闻)
  • 企业应用广泛
  • Redis 的所有操作都是原子性的,意味着要么成功执行要么失败完全不执行。单个操作是原子性的。
  • 由于数据是存放在内存中,所以存储的数据量会受到物理内存的限制,而且成本较高。
  • 虽然 Redis 提供了持久化的功能,但是如果在数据写入磁盘之前发生了断电等异常,那么最新的数据就会丢失。

安装方式

图形化管理工具 RedisInsight

本次使用docker安装

1)本地安装

1
2
3
4
5
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

sudo apt-get update
sudo apt-get install redis

2)docker安装

1
2
3
4
5
6
7
8
//安装
$ docker pull redis:latest
//查看是否成功安装
$ docker images
//运行(此时可以配置密码,详情见后文)
$ docker run -itd --name redis-test -p 6379:6379 redis
//查看运行信息
$ docker ps

-p 6379:6379:映射容器服务的 6379 端口到宿主机的 6379 端口。外部可以直接通过宿主机ip:6379 访问到 Redis 的服务。

使用redis-cli

1)无密码时

1
2
3
//通过 redis-cli 连接测试使用 redis 服务
~:$ docker exec -it redis-test /bin/bash
root@2b47c842f4b0:/data# redis-cli -h localhost -p 6379

redis-cli -h localhost -p 6379 “-h”指定ip地址 “-p”指定端口号

链接本地直接 redis-cli 即可

2)有密码时

1
2
3
4
root@2b47c842f4b0:/data# redis-cli -a [password]
//或者
root@2b47c842f4b0:/data# redis-cli
127.0.0.1:6379> auth [password]

配置密码

1)为现有的redis创建密码

1
2
3
4
//先执行 redis-cli 命令
config set requirepass [password]
//查看密码
config get requirepass

2)创建Redis容器时设置密码

1
$ docker run --name redis -p 6380:6379 redis-test --requirepass [password]

数据类型

  • 字符串(string):普通字符串,Redis中最简单的数据类型
  • 哈希(hash):也叫散列,类似与Java中的HashMap结构
  • 列表(list):按照插入的顺序排序,可以有重复元素,类似Java中的LinkedLIst
  • 集合(set):无序集合,没有重复元素,类似Java中的HashSet
  • 有序集合(sorted set/zset):集合中的每个元素关联一个double类型的分数(score),根据分数升序排序,没有重复元素

字符串操作命令

  • SET key value 设置指定key的值
  • GET key 获取指定key的值
  • SETEX key seconds value 设置指定key的值,并将key的过期时间设置为seconds秒
  • SETNX key value 只有在key不存在时设置key的值
  • DEL key 删除指定的key

哈希操作命令

  • HSET key field value 设置哈希表key中字段field的值为value
  • HGET key field 获取存储在哈希表中指定字段的值
  • HDEL key field 删除存储在哈希表中指定字段
  • HKEYS key 获取哈希表中所有字段
  • HVALS key 获取哈希表中所有值

列表操作命令

  • LPUSH key value1 [value2] 将一个或多个值插入到列表头部
  • LRANGE key start stop 获取列表指定范围内的元素
  • RPOP key 移除并获取列表最后一个元素
  • LLEN key 获取列表长度

集合操作命令

  • SADD key member1 [member1] 向集合中添加一个或多个成员
  • SMEMBERS key 返回集合中的所有成员
  • SCARD key 获取集合的成员数
  • SINTER key1 [key2] 返回给定所有集合的交集
  • SUNION key1 [key2] 返回给定所有集合的并集
  • SREM key membder1 [membder1] 删除集合中的一个或多个成员

有序集合操作命令

  • ZADD key score1 member1 [score2 member1] 向有序集合中添加一个或多个成员
  • ZRANGE key start stop [WITHSCORE] 通过索引区间返回有序集合中指定区间内的成员
  • ZINCRBY key increment member 有序集合中对指定成员的分数加上增量increment
  • ZREM key membder [membder…] 移除有序集合中的一个或多个成员

通用命令

  • KEYS pattern 查找所有符合给定模式(pattern)的key
  • EXITS key 检查给定key是否存在
  • TYPE key 返回key所储存的值的类型
  • DEL key 该命令用于在key存在时删除key

在Java中使用Redis(Spring Data Redis方式)

1)在poe.xml中导入Spring Data Redis 的maven坐标

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2)在application.yml中配置Redis数据源

1
2
3
4
5
6
spring:
redis:
host: localhost
port: 6379
password:
database: 0

3)编写配置类,创建RedisTemplate对象,在config目录下创建RedisConfiguration类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
@Slf4j
public class RedisConfiguration {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
log.info("开始创建redis模板对象");
RedisTemplate redisTemplate = new RedisTemplate();
//设置redis的连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置redis key的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}

4)通过RedisTemplate对象操作Redis

1
2
3
4
5
6
7
8
9
10
//String 字符串
ValueOperations valueOperations = redisTemplate.opsForValue();
//Hash 哈希
HashOperations hashOperations = redisTemplate.opsForHash();
//List 列表
ListOperations listOperations = redisTemplate.opsForList();
//sorted set/zset 有序集合
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
//Set 集合
SetOperations setOperations = redisTemplate.opsForSet();

在Java中操作Redis

使用前先注入

1
2
@Autowired
private RedisTemplate redisTemplate;

String 字符串操作

1
2
3
4
5
6
7
8
9
10
11
12
public void testString(){
//set
redisTemplate.opsForValue().set("city","beijing");
//get
String city = (String) redisTemplate.opsForValue().get("city");
System.out.println(city);
//setex
redisTemplate.opsForValue().set("code","1234",3, TimeUnit.MINUTES);
//setnx
redisTemplate.opsForValue().setIfAbsent("lock","1");
redisTemplate.opsForValue().setIfAbsent("lock","2");
}

操作哈希类型数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void testHash(){
HashOperations hashOperations = redisTemplate.opsForHash();
//hset
hashOperations.put("100","name","tom");
hashOperations.put("100","age","20");
//hget
String name = (String) hashOperations.get("100", "name");
System.out.println(name);
//hkeys
Set keys = hashOperations.keys("100");
System.out.println(keys);
//hvals
List values = hashOperations.values("100");
System.out.println(values);
//hdel
hashOperations.delete("100","age");
}

操作列表类型数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testList(){
ListOperations listOperations = redisTemplate.opsForList();
//lpush
listOperations.leftPushAll("myList","a","b","c");
listOperations.leftPush("myList","d");
//lrange
List myList = listOperations.range("myList", 0, -1);
System.out.println(myList);//[d, c, b, a]
//rpop
listOperations.rightPop("myList");
//llen
Long size = listOperations.size("myList");
System.out.println(size);//3
}

操作集合类型数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Test
public void testSet(){
SetOperations setOperations = redisTemplate.opsForSet();
//sadd
setOperations.add("set1","a","b","c","d");
setOperations.add("set2","a","b","x","y");
//smembers
Set members = setOperations.members("set1");
System.out.println(members);//[a, b, c, d]
//scard
Long size = setOperations.size("set1");
System.out.println(size);//4
//sinter
Set intersect = setOperations.intersect("set1", "set2");
System.out.println(intersect);//[a, b]
//sunion
Set union = setOperations.union("set1", "set2");
System.out.println(union);//[a, b, c, d, x, y]
//srem
setOperations.remove("set1","a","b");
}

操作有序集合类型数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testZSet(){
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
//zadd
zSetOperations.add("zset1","a",10);
zSetOperations.add("zset1","b",12);
zSetOperations.add("zset1","c",9);
//zrange
Set zset1 = zSetOperations.range("zset1", 0, -1);
System.out.println(zset1);//[c, a, b]
//zincrby
zSetOperations.incrementScore("zset1","c",10);
//zrem
zSetOperations.remove("zset1","a","b");
}

通用命令操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
public void testCommon(){
//keys
Set keys = redisTemplate.keys("*");
System.out.println(keys);
//exits
Boolean name = redisTemplate.hasKey("name");
Boolean set1 = redisTemplate.hasKey("set1");
//type
for(Object key : keys) {
DataType type =redisTemplate.type(key);
System.out.println(type.name());
}
//del
redisTemplate.delete("myList");
}