一篇搞定 Redis6(完整版)

Posted xhmj12

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇搞定 Redis6(完整版)相关的知识,希望对你有一定的参考价值。


 

作者:Mrwhite86 | 来源:urlify.cn/qYZRZr

一、Nosql与Redis概述

1、Nosql的优势

(1)使用nosql解决cpu与内存压力

(2)使用nosql解决I/O压力

2、Nosql数据库的概述

(1)NoSql= Not Only SQL

(2)采用key-value模式存储

(3)不遵循SQL标准

(4)性能远超过SQL

3、使用场景

(1)数据的高并发读写

(2)海量数据读写

(3)数据可扩展性

4、不适用场景

需要事务的支持

基于sql的结构化查询存储,需要即席查询

5、 Redis概述

(1)开源的key-value系统

(2)支持String、List、Set、zset、hash等数据类型

(3)数据库支持push/pop/add/remove操作

(3)支持不同方式的排序

(4)可写入内存也可以持久化

(5)主从同步功能

二、Redis6安装与使用

1、官网下载:放入liunx对应目录内

https://redis.io/

2、安装gcc编译环境

yum install centos-release-scl scl-utils-build

yum install -y devtoolset-8-toolchain

scl enable devtoolset-8 bash

测试gcc版本

gcc -version

 3、解压缩:

tar zxvf redis-6.2.4.tar.gz

4、进入redis-6.2.4目录执行make命令

 5、执行安装make install

6、验证安装成

cd /usr/local/bin
ll

 7、相关软件介绍:

redis-benchmar:性能测试工具

redis-check-aof:修改有问题的AOF

redis-check-rdb:修改有问题的rdb文件

redis-sentinel:Redis的集群使用

redis-server:Redis服务器集群使用

redis-cli:客户端,操作入口

8、前台启动(不推荐)

9、后台启动

(1) 复制配置文件

cp -r redis.conf /opt/

(2)修改参数配置,将daemonize no改为daemonize yes,让服务支持在后台启动

[root@localhost redis-6.2.4]# cd /opt/
[root@localhost opt]# vi redis.conf

 (3)启动redis

[root@localhost bin]# cd /usr/local/bin/
[root@localhost bin]# redis-server /opt/redis.conf 
[root@localhost bin]# ps -ef|grep redis

 (4)使用redis-cli测试

 10、redis关闭

(1)redis-cli shutdown(进入终端shutdown也可以)

(2)kill -9 xxx(进程)

三、常用五大数据类型

1、Redis key操作

(1)查看所有key:keys *

127.0.0.1:6379> keys *
(empty array)

(2)添加 key value:set

127.0.0.1:6379> set k1 lucy
OK
127.0.0.1:6379> set k2 mary
OK
127.0.0.1:6379> set k3 jack
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"

(3)判断key是否存在 exists

127.0.0.1:6379> exists k1
(integer) 1
127.0.0.1:6379> exists k4
(integer) 0

(4)查看key的类型:type

127.0.0.1:6379> type k1
string

(5)删除key数据:del

127.0.0.1:6379> del k1
(integer) 1

(6)选择非阻塞删除:unlink(异步删除)

127.0.0.1:6379> unlink k2
(integer) 1

(7)设置key的过期时间(秒):expire

127.0.0.1:6379> expire k3 10
(integer) 1

(9)查看ttl过期时间(秒):ttl(-1永久不过期,-2已经过期)

127.0.0.1:6379> ttl k3
(integer) -2

(10)切换数据库:select

127.0.0.1:6379[1]> select 0
OK

(11)查看当前数据库的key数量:dbsize

127.0.0.1:6379> dbsize
(integer) 1

(12)清空当前库内数据(慎用)

127.0.0.1:6379> flushdb
OK

(13)通杀所有库内数据(慎用)

127.0.0.1:6379> flushall
OK

2、Redis字符串(String)

(1)简介:字符串,一个key对应一个value,是二进制安全的,是Redis最基本数据类型,value最多512M,底层为动态字符串,ArrayList

(2)设置值,相同key值覆盖:set

set k1 v100

 (3)获取值:get

get k1

 (4)追加值:append,返回总长度

append k1 abcd

(5)获取值的长度:strlen

strlen k1

 (6)当key存在时操作:setnx,设置成功返回1,设置失败返回0

1

setnx k1 v1

 (7)将数字类型值+1/-1:incr/decr,原子性操作,不受多线程机制打断。

incr k3
decr k3

 (8)将key存储的数字值递增x/递减x:incrby/decrby

incrby k3 10
decrby k3 5

msetnx k11 v11 k12 v12 k13 v13
msetnx k1 v11 k4 v4

 (9)同时设置一个或多个key-value键值对:mset

mset k1 v1 k2 v2 k3 v3

(10)同时获取一个或多个value:mget

mget k1 k2 k3

(11)设置多个key-value(当key都不存在时设置成功):msetnx

127.0.0.1:6379> msetnx k11 v11 k12 v12 k13 v13
(integer) 1
127.0.0.1:6379> msetnx k1 v11 k4 v4
(integer) 0

 (12)获取范围的值(开始-结束):getrange

127.0.0.1:6379> getrange name 0 3
"luck"

 (13)设置范围的值(开始位置-覆盖):setrange,返回总长度

127.0.0.1:6379> setrange name 3 abc
(integer) 8

 (14)设置key的同时设置过期时间:setex

127.0.0.1:6379> setex age 20 value30
OK

 (15)以新值换旧值(显示旧值):getset

127.0.0.1:6379> getset name jack
"lucabcry"

3、Redis列表(List)

(1)简介:单键多值的字符串列表,可以按照插入顺序排序,底层为双向链表(zipList(数据少时)->quickList(数据多时))

(2)从左边/右边插入一个或多个值:lpush/rpush,返回数组长度

127.0.0.1:6379> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379> rpush k1 v7 v8 v9
(integer) 6

(3)按照索引下标(范围)获取元素,从左到右(0表示左边第一个,-1表示右边第一个):lrange

127.0.0.1:6379> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
4) "v7"
5) "v8"
6) "v9"

(4)从左边或右边取出一个值:lpop/rpop

127.0.0.1:6379> lpop k1
"v3"
127.0.0.1:6379> rpop k1
"v9"

(5)从k1列表右边吐出一个值,插入到v2列表的左边:rpoplpush

127.0.0.1:6379> rpoplpush k1 k2
"v1"

(6)按照索引下标(单值)获取元素(从左到右):lindex

127.0.0.1:6379> lindex k2 0
"v1"

(7)获取列表的长度:llen

llen k1

(8)在key对应的value前面/后面插入new value:linset before/after

127.0.0.1:6379> linsert k1 before "v3" "v31"
(integer) 3
127.0.0.1:6379> linsert k1 after "v2" "v21"
(integer) 4

 (9)从左边删除n个对应的value:lrem

127.0.0.1:6379> lrem k1 2 "new11"
(integer) 2

 (10)将列表key下标为index的值替换成value:lset

127.0.0.1:6379> lset k1 1 "new31"
OK

4、Redis集合(Set)

(1)Redis Set是String类型的无序集合,它的底层其实是一个value为null的hash表,value自动排重且无序

(2)将一个或多个元素加入到集合key中:sadd,已经存在元素将忽略

127.0.0.1:6379> sadd k1 v1 v2 v3
(integer) 3

(3)取出集合中的所有值:smembers

127.0.0.1:6379> smembers k1
1) "v3"
2) "v2"
3) "v1"

 (4)判断key集合中是否包含对应的value:sismember,1有0无

127.0.0.1:6379> sismember k1 v1
(integer) 1

 (5)返回集合中元素个数:scard

127.0.0.1:6379> scard k1
(integer) 3

 (6)从集合中删除某一个或多个元素:srem

127.0.0.1:6379> srem k1 v1
(integer) 1

 (7)随机从该集合吐出一个元素:spop

127.0.0.1:6379> spop k1
"v3"

 (8)随机从集合中取出n个值,不会从集合中删除:srandmember

127.0.0.1:6379> srandmember k1 2
1) "v1"
2) "v2"

(9)把集合中的一个值从一个集合移动到另一个集合:smove

127.0.0.1:6379> smove k1 k2 v3
(integer) 1

(10)取两个集合的交集/并集/差集(key1中存在,key2中不存在):sinter/sunoin/sdiff

127.0.0.1:6379> sinter k2 k3
1) "v4"
127.0.0.1:6379> sunion k2 k3
1) "v3"
2) "v5"
3) "v4"
4) "v7"
5) "v6"
127.0.0.1:6379> sdiff k2 k3
1) "v3"
2) "v5"


 5、Redis哈希(Hash)

(1)简介:是一个String类型的field和value的映射表,hash适合用来存储对象。类似java中Map<String,Object>,底层为zipList(数据量少)或hashtable(数据量较多)

在公众号互联网架构师后台回复“2T”,获取一份惊喜礼包。

(2)向hash内添加数据(key-field-value):hset

127.0.0.1:6379> hset user:1001 id 1
(integer) 1
127.0.0.1:6379> hset user:1001 name zhangsan
(integer) 1

(3)从集合中取出数据(key-field):hget

127.0.0.1:6379> hget user:1001 id
"1"
127.0.0.1:6379> hget user:1001 name
"zhangsan"

 (4)批量添加数据:hmet

127.0.0.1:6379> hmset user:1002 id 2 name lisi age 30
OK

(5)判断哈希表key中,field是否存在:hexists,1有0无

127.0.0.1:6379> hexists user:1002 id
(integer) 1
127.0.0.1:6379> hexists user:1002 name
(integer) 1
127.0.0.1:6379> hexists user:1002 gender
(integer) 0


(6)查看哈希表中所有field:hkeys

127.0.0.1:6379> hkeys user:1002
1) "id"
2) "name"
3) "age"

(7)查看哈希表内所有value:hvals

127.0.0.1:6379> hvals user:1002
1) "2"
2) "lisi"
3) "30"

(8)对应的key、field的值增量+1:hincrby

127.0.0.1:6379> hincrby user:1002 age 2
(integer) 32

(9)添加数据,仅当field不存在时:hsetnx

127.0.0.1:6379> hsetnx user:1002 age 40
(integer) 0
127.0.0.1:6379> hsetnx user:1002 gender 1
(integer) 1

6、Redis有序集合(Zset)

(1)简介:有序的,类似set,没有重复元素,关联了score并可以进行排序,底层架构类似Map<String,value>,Zset底层为hash以及跳跃表

(2)将一个或多个元素以及score<key><score1><value1><score2><value2>加入到有序集合key中:zadd

127.0.0.1:6379> clear
127.0.0.1:6379> zadd topn 200 java 300 c++ 400 mysql 500 php
(integer) 4

 (3)取出返回有序集合key中,下标在<start><stop>之间:zrange,自动按照score排序,[withscores]可以返回评分

127.0.0.1:6379> zrange topn 0 -1
1) "java"
2) "c++"
3) "mysql"
4) "php"
127.0.0.1:6379> zrange topn 0 -1 withscores
1) "java"
2) "200"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "php"
8) "500"

 (4)取出score值介于min和max之间的成员,按照score从小到大排序:zrangebyscore <key><min><max>[withscores][limit offset count]

127.0.0.1:6379> zrangebyscore  topn 300 500  withscores 
1) "c++"
2) "300"
3) "mysql"
4) "400"
5) "php"
6) "500"


 (5)zrevngebyscore <key><max><min>[withscores][limit offset count]

127.0.0.1:6379> zrevrangebyscore  topn 500 300  withscores 
1) "php"
2) "500"
3) "mysql"
4) "400"
5) "c++"
6) "300"

 (6)为元素score加上增量:zincrby<key><increment><value>

127.0.0.1:6379> zincrby topn 50 java
"250"

(7)删除该集合中下,指定元素的值:zrem<key><value>

127.0.0.1:6379> zrem topn php
(integer) 1

(8)统计该集合,分数区间内的元素个数:zcount<key><min><max>

127.0.0.1:6379> zcount topn 200 300
(integer) 2

(9)返回该值在集合中的排名,从0开始:zrank<key><value>

127.0.0.1:6379> zrank topn c++
(integer) 1

四、Redis6配置文件详解

 1、units单位:

只支持bytes,支持bit,不区分大小写

2、INCLUDES:

包含其他的配置文件

 3、NETWORK:网络相关配置

(1)bind:限定是否只能本机连接等

(2)protected-mode:是否开启本机保护模式,只可本机访问

(3)port:默认端口号6379

(4)tcp-backlog:正在进行三次握手的队列总和默认值为511

(5)timeout:超时时间默认0,永不超时

(6)tcp-keepalive:检测心跳时间默认300秒

(7)daemonize:是否支持后台启动

 (8)pidfile:保存对应的进程号文件

(9)loglevel:保存日志的级别

(10)logfile:设置日志的路径

(11)databases:默认使用16个库

(12)Security密码设置:

#  foobared 取消注释,设置对应的密码信息

在公众号互联网架构师后台回复“2T”,获取一份惊喜礼包。

(13)LIMITS限制:

maxclients:最大连接数,默认10000

  (14)maxmemory:内存上限:

五、Redis6的发布和订阅

1、发布与订阅:

(1)发送者:pub发送消息

(2)订阅者:sub接受消息

redis客户端可以订阅任意数量的频道

2、发布订阅流程

(1)客户端可以订阅频道

(2)当这个频道发布消息后,消息就会发送给订阅的客户端

3、发布订阅的命令行实现

 (1)打开一个客户端订阅channel1

127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1

 (2)打开另一个客户端,给channel1发布消息hello

127.0.0.1:6379> publish channel1 hello
(integer) 1

 (3)打开第一个客户端,可以看到发送的消息

127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1
1) "message"
2) "channel1"
3) "hello"

六、Redis6新数据类型

1、Bitmaps

(1)简介:实现对字符串的位的操作的字符串。是一个以位位单元的数组,数组每个单元只能存储0与1,下标与偏移量,与set相比节省gongjinaq

(2)设置Bitmaps中某个偏移量的值(0或1):setbit<key><offset><value>

127.0.0.1:6379> setbit users:20210101 1 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 6 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 11 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 15 1
(integer) 0
127.0.0.1:6379> setbit users:20210101 19 1
(integer) 0

 (3)获取Bitmaps中某个偏移量的值:getbit<key><offset>

127.0.0.1:6379> getbit users:20210101 1
(integer) 1

(4)统计字符串被设置位1的bit数量:bitcount[begin][end]

127.0.0.1:6379> bitcount users:20210101
(integer) 5
127.0.0.1:6379> bitcount users:20210101 1 5
(integer) 3

(5)复合操作(交集/并集/非/异或):bitop and/or/not/xor

设置初始数据:

127.0.0.1:6379> setbit unique:users:20201104 1 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201104 2 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201104 5 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201104 9 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 0 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 1 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 4 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20201103 9 1
(integer) 0

计算出两天都访问过网站的用户数量:(1与9号用户两天都访问了)

127.0.0.1:6379> bitop and unique:users:and:20201104_03 unique:users:20201103 unique:users:20201104
(integer) 2127.0.0.1:6379> bitcount unique:users:and:20201104_03
(integer) 2

计算出任意一天都访问过网站的用户数量

127.0.0.1:6379> bitop or unique:users:or:20201104_03 unique:users:20201103 unique:users:20201104
(integer) 2
127.0.0.1:6379> bitcount unique:users:or:20201104_03
(integer) 6

2、HyperLogLog

(1)简介:

适用于独立IP数、搜索记录等需要去重和计数时。

(2)添加指定元素到HyperLogLog:pdadd<key><element>[element],1成功0失败

127.0.0.1:6379> pfadd program "java"
(integer) 1
127.0.0.1:6379> pfadd program "php"
(integer) 1
127.0.0.1:6379> pfadd program "java"
(integer) 0
127.0.0.1:6379> pfadd program "c++" "mysql"
(integer) 1

(3)统计HLL的pfcount<key> 

127.0.0.1:6379> pfcount program
(integer) 4

(4)将一个或多个HLL合并的结果存储在另一个HLL:pfmeger

127.0.0.1:6379> pfmerge k100 k1 program
OK

3、Geospatial

(1)简介:redis3.2后增加GEO类型,即地理信息的缩写,提供了经纬度的设置、查询、范围查询、举例查询、经纬度hash等

(2)加地理位置(经度、纬度、名称):geoadd<key><longitude><latitude><member>[<longitude><latitude><member>]...

有效经纬度:-180°-180°,纬度:-85.05112878°-85.05112878°

127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing 114.05 22.52 shenzhen 116.38 39.90 beijing
(integer) 3

(3)获取指定地区的坐标值:geoos<key><member>[member]...

127.0.0.1:6379> geopos china:city shanghai
1) 1) "121.47000163793563843"
   2) "31.22999903975783553"
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.38000041246414185"
   2) "39.90000009167092543"

 (4)获取两个位置之间的直线距离:geodist<key><member2><member2><单位>

127.0.0.1:6379> geodist china:city beijing shanghai km
"1068.1535"

(5)以给定的经纬度为中心,找出某一半径内的元素:georadius<key><longitude><latitude>radius m|km|ft|mi

127.0.0.1:6379> georadius china:city 110 30 1000 km
1) "chongqing"
2) "shenzhen"

七、Jedis操作Redis6

1、idea建立maven工程

2、引入相关依赖:

<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.2.0</version>
        </dependency>

3、jedis连接redis测试(Maven)

package com.testbk.jedis;
import redis.clients.jedis.Jedis;

public class jedisDemo1 {
    public static void main(String[] args) {
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //测试
        String value = jedis.ping();
        System.out.println(value);
    }
}

显示结果如下:

PONG

4、Jedis-API:操作key

//操作key
    @Test
    public void demo1(){
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //清空redis
        jedis.flushDB();
        //添加数据
        jedis.set("k1","v1");
        jedis.set("k2","v2");
        jedis.set("k3","v3");
        //查询所有key值
        Set<String> keys = jedis.keys("*");
        for(String key:keys){
            System.out.println(key);
        }
        //根据key获取value
        String value = jedis.get("k1");
        System.out.println("k1对应的value为:"+value);
    }

查看运行结果:

k3
k1
k2
k1对应的value为:v1

5、Jedis-API:操作String

//操作String
    @Test
    public void demo2(){
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //清空redis
        jedis.flushDB();
        //添加多个数据
        jedis.mset("str1","v1","str2","v2","str3","v3");
        //查询所有key值
        System.out.println(jedis.mget("str1","str2","str3"));
    }

查看运行结果:

[v1, v2, v3]

6、Jedis-API:操作List

//操作List
    @Test
    public void demo3(){
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //清空redis
        jedis.flushDB();
        //添加数据
        jedis.lpush("k1","lucy","mary","jack");
        //查询数据
        List<String> value = jedis.lrange("k1", 0, -1);
        System.out.println(value);
    }

查看运行结果:

[jack, mary, lucy]

7、Jedis-API:操作set

//操作set
    @Test
    public void demo4(){
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //清空redis
        jedis.flushDB();
        //添加数据
        jedis.sadd("name","luck","mary","jack");
        //查询数据
        Set<String> names = jedis.smembers("name");
        System.out.println(names);
    }

查看运行结果:

[jack, mary, luck]

8、Jedis-API:操作set

//操作set
    @Test
    public void demo4(){
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //清空redis
        jedis.flushDB();
        //添加数据
        jedis.sadd("orders","order1");
        jedis.sadd("orders","order2");
        jedis.sadd("orders","order3");
        jedis.sadd("orders","order4");
        //查询数据
        Set<String> orders1 = jedis.smembers("orders");
        System.out.println(orders1);
        //删除后再查询
        jedis.srem("orders","order1");
        Set<String> orders2 = jedis.smembers("orders");
        System.out.println(orders2);
    }

查看运行结果:

[order3, order4, order1, order2]
[order3, order4, order2]

9、Jedis-API:操作Hash

//操作Hash
    @Test
    public void demo5(){
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //清空redis
        jedis.flushDB();
        //添加数据
        jedis.hset("users","age","20");
        //查询数据
        String hget = jedis.hget("users", "age");
        System.out.println(hget);
    }

查看运行结果:

20

10、Jedis-API:操作Zset

//操作Zset
    @Test
    public void demo6(){
        //创建Jedis对象,需要修改redis.conf的bind(注释)与protected-mode(no)配置
        Jedis jedis =new Jedis("192.168.37.8",6379);
        //清空redis
        jedis.flushDB();
        //添加数据
        jedis.zadd("china",100d,"shanghai");
        //查询数据
        Set<String> china = jedis.zrange("china", 0, -1);
        System.out.println(china);
    }

查看运行结果:

[shanghai]

八、Redis6与Spring Boot整合

1、idea创建springboot工程

 

 2、pom文件引入springboot-redis的两个依赖 

<!--redis-->
        <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>
            <version>2.6.0</version>
        </dependency>

3、springboot配置文件中配置redis相关内容

文件位置为resources下面的application.properties

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

4、创建redis配置类:

package com.testbk.redis_springboot.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

5、编写RedisTestControll添加测试方法:

package com.testbk.redis_springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/redisTest")
public class RedisTestController {
    @Autowired
    private RedisTemplate redisTemplate;
    @GetMapping
    public String testRedis(){
        //设置值到redis
        redisTemplate.opsForValue().set("name","lucy");
        //从redis获取值
        String name = (String)redisTemplate.opsForValue().get("name");
        return  name;
    }
}

6、启动类启动Springboot类:RedisSpringbootApplication

在公众号互联网架构师后台回复“2T”,获取一份惊喜礼包。

 显示运行结果:

.   ____          _            __ _ _
 /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\
( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\
 \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.1)

浏览器访问验证:http://localhost:8080/redisTest,显示结果:

lucy

九、Redis6的事务操作

1、Redis事务定义

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

Redis事务的主要作用就是串联多个命令防止别的命令插队

2、Multi、Exec、discard

(1)基本概念

输入Multi命令开始:输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。

组队的过程中可以通过discard来放弃组队

正常场景:

异常场景2种:

 

3、事务命令演示

(1)组队-执行案例

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key1 value1 
QUEUED
127.0.0.1:6379(TX)> set key2 value2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK

(2)组队-取消案例

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set a1 v1
QUEUED
127.0.0.1:6379(TX)> set a2 v2
QUEUED
127.0.0.1:6379(TX)> discard
OK

(3)组队-错误处理

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set b1 v1
QUEUED
127.0.0.1:6379(TX)> set b2 v2
QUEUED
127.0.0.1:6379(TX)> set b3 
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.

(4)组队-执行-错误处理

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set c1 v1
QUEUED
127.0.0.1:6379(TX)> incr c1
QUEUED
127.0.0.1:6379(TX)> set c2 v2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK

4、事务冲突的问题

场景:多个人同时使用一个账户,参加双十一抢购,购买不同的商品,未加事务会产生冲突。

(1)悲观锁

每次拿数据适都认为别人会修改,所以每次在拿数据适都会上锁,这样别人想拿数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁,读锁,写锁,都是操作前上锁。

(2)乐观锁 

每次拿数据的适合都认为别人不会修改,所以不会上锁,但是

以上是关于一篇搞定 Redis6(完整版)的主要内容,如果未能解决你的问题,请参考以下文章

个人整理的Redis6的思维导图

甘道夫HBase基本数据操作详解完整版,绝对精品

第一篇:版本控制git之仓库管理

大数据从零基础到精通视频教程 完整版

软件测试从业者,试用期生存指南(完整版)

怒火攻心2:高压电高清完整版下载