Redis学习
一、NoSql数据库简介
1.1 、技术发展
1、解决功能性问题:JAVA、JSP、Linux
2、解决扩展性问题:Spring、Mybatis
3、解决性能问题:NoSQL、Hadoop、MQ
1.2、NoSQL数据库的作用
1.2.1解决内存、CPU压力
1.2.2、解决IO问题
1.3、NoSQL数据库介绍
1.3.1、NoSQL数据库概述
NoSQL(Not Only SQL)不仅仅是SQL、泛指非关系型数据库,NoSQL不依赖业务逻辑方式存储、二是key-value模式存储,因此大大增加了数据库的扩展能力。
以性能最优先存储数据。
- 不支持SQL标准;
- 不支持ACID
- 远超于SQL的性能
1.3.2、NoSQL的应用场景
- 数据高并发的读写;
- 海量数据读写;
- 数据高可扩展性;
1.3.3、NoSQL不支持的场景
需要事务支持;
基于SQL的结构化查询存储、处理负责的关系、需要即席查询;
1.3.4、常见的NoSQL数据库
Memcache
Redis
MongoDB
1.3.5、数据存储类型
行式数据库
列式数据库
二、Redis概述和安装
2.1 概述
Redis是一个开源的key-value存储系统;
支持字符串、链表、set集合等多种类型;
操作是原子性的;
周期性把数据存储到磁盘中;
2.2、安装
2.2.1、官网:https://redis.io/
下载上传安装包
2.2.2、安装依赖
[root@localhost ~]# yum install gcc -y
查看版本
[root@localhost ~]# gcc --version gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44) Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2.2.3、解压
[root@localhost Redis]# tar -zxvf redis-6.2.1.tar.gz
2.2.4、编译
[root@localhost Redis]# cd redis-6.2.1 [root@localhost redis-6.2.1]# ls 00-RELEASENOTES CONTRIBUTING INSTALL README.md runtest-cluster sentinel.conf TLS.md BUGS COPYING Makefile redis.conf runtest-moduleapi src utils CONDUCT deps MANIFESTO runtest runtest-sentinel tests [root@localhost redis-6.2.1]# make
完成是这样的
INSTALL redis-sentinel CC redis-cli.o CC cli_common.o LINK redis-cli CC redis-benchmark.o LINK redis-benchmark INSTALL redis-check-rdb INSTALL redis-check-aof Hint: It's a good idea to run 'make test' ;) make[1]: Leaving directory `/root/Redis/redis-6.2.1/src'
安装
[root@localhost redis-6.2.1]# make install cd src && make install make[1]: Entering directory `/root/Redis/redis-6.2.1/src' Hint: It's a good idea to run 'make test' ;) INSTALL install INSTALL install INSTALL install make[1]: Leaving directory `/root/Redis/redis-6.2.1/src'
查看
[root@localhost redis-6.2.1]# cd /usr/local/bin [root@localhost bin]# ll total 18844 -rwxr-xr-x 1 root root 4833384 Nov 12 22:02 redis-benchmark lrwxrwxrwx 1 root root 12 Nov 12 22:02 redis-check-aof -> redis-server lrwxrwxrwx 1 root root 12 Nov 12 22:02 redis-check-rdb -> redis-server -rwxr-xr-x 1 root root 5003400 Nov 12 22:02 redis-cli lrwxrwxrwx 1 root root 12 Nov 12 22:02 redis-sentinel -> redis-server -rwxr-xr-x 1 root root 9450232 Nov 12 22:02 redis-server
2.3、启动
2.3.1、前台启动 /usr/local/bin
[root@localhost bin]# ll total 18844 -rwxr-xr-x 1 root root 4833384 Nov 12 22:02 redis-benchmark lrwxrwxrwx 1 root root 12 Nov 12 22:02 redis-check-aof -> redis-server lrwxrwxrwx 1 root root 12 Nov 12 22:02 redis-check-rdb -> redis-server -rwxr-xr-x 1 root root 5003400 Nov 12 22:02 redis-cli lrwxrwxrwx 1 root root 12 Nov 12 22:02 redis-sentinel -> redis-server -rwxr-xr-x 1 root root 9450232 Nov 12 22:02 redis-server [root@localhost bin]# redis-server 5980:C 12 Nov 2023 22:11:47.266 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 5980:C 12 Nov 2023 22:11:47.266 # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=5980, just started 5980:C 12 Nov 2023 22:11:47.266 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf 5980:M 12 Nov 2023 22:11:47.267 * Increased maximum number of open files to 10032 (it was originally set to 1024). 5980:M 12 Nov 2023 22:11:47.267 * monotonic clock: POSIX clock_gettime _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.1 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 5980 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 5980:M 12 Nov 2023 22:11:47.268 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 5980:M 12 Nov 2023 22:11:47.268 # Server initialized 5980:M 12 Nov 2023 22:11:47.268 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 5980:M 12 Nov 2023 22:11:47.268 * Ready to accept connections
2.3.2、后台启动
准备修改配置文件
[root@localhost ~]# cd Redis/ [root@localhost Redis]# ls redis-6.2.1 redis-6.2.1.tar.gz [root@localhost Redis]# cd redis-6.2.1 [root@localhost redis-6.2.1]# ls 00-RELEASENOTES CONTRIBUTING INSTALL README.md runtest-cluster sentinel.conf TLS.md BUGS COPYING Makefile redis.conf runtest-moduleapi src utils CONDUCT deps MANIFESTO runtest runtest-sentinel tests [root@localhost redis-6.2.1]# cp redis.conf redis.conf.bak
修改配置文件
[root@localhost redis-6.2.1]# vi redis.conf daemonize yes
回到bin目录下启动
[root@localhost ~]# cd /usr/local/bin/ [root@localhost bin]# redis-server /root/Redis/redis-6.2.1/redis.conf
查看
[root@localhost bin]# ps -ef | grep redis root 6001 1 0 22:24 ? 00:00:00 redis-server 127.0.0.1:6379 root 6007 1521 0 22:25 pts/0 00:00:00 grep --color=auto redis
2.3.3、用客户端连接访问
[root@localhost bin]# redis-cli 127.0.0.1:6379> ping PONG
2.3.4、关闭redis
客户端关闭
[root@localhost bin]# redis-cli 127.0.0.1:6379> shutdown
或者kill进程号
[root@localhost bin]# ps -ef | grep redis root 6015 1 0 22:28 ? 00:00:00 redis-server 127.0.0.1:6379 root 6021 1521 0 22:28 pts/0 00:00:00 grep --color=auto redis [root@localhost bin]# kill -9 6015
2.4、Redis相关知识
Redis默认16个数据库,默认用0号库;
Redis是单线程+多路IO复用技术;
三、常用的五大数据类型
3.1、常用的数据类型
Redis字符串(String)
Redis列表(List)
Redis集合(Set)
Redis哈希(Hash)
Redis有序集合(Zset)
3.2、常用操作
3.2.1、Redis键
[root@localhost bin]# redis-cli 127.0.0.1:6379> set k1 xue OK 127.0.0.1:6379> set k2 bao OK 127.0.0.1:6379> set k3 long OK
查看key:
127.0.0.1:6379> keys * 1) "k2" 2) "k1" 3) "k3"
3.2.2、判断key是否存在:
127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> exists k4 (integer) 0
3.2.3 、查看值的类型:
127.0.0.1:6379> type k2 string 127.0.0.1:6379> type k3 string
3.2.4、删除key
127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> del k3 (integer) 1
3.2.5、unlink
非阻塞删除,先从元数据删除,真正的删除后续异步操作
127.0.0.1:6379> unlink k5 (integer) 1
3.2.6、expire
给key设置过去时间
127.0.0.1:6379> expire k1 10 (integer) 0
查看key的过期时间
127.0.0.1:6379> ttl k1 (integer) -2
3.2.7、切换库
127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> select 0 OK
3.2.8、统计key的数量
127.0.0.1:6379> dbsize (integer) 3
3.2.9 flushdb清空当前库
127.0.0.1:6379> flushdb OK 127.0.0.1:6379> keys * (empty array)
3.3、字符串String
一个Redis字符串value最多可以是512M;
3.3.1、set命令
添加键值对:
127.0.0.1:6379> set k1 v100 OK 127.0.0.1:6379> set k2 v200 OK 127.0.0.1:6379> set k3 v300 OK 127.0.0.1:6379> keys * 1) "k2" 2) "k1" 3) "k3"
3.3.2、查看key的值
127.0.0.1:6379> get k1 "v100" 127.0.0.1:6379> get k2 "v200" 127.0.0.1:6379> get k3 "v300"
3.3.3、给key追加value
127.0.0.1:6379> append k1 abc (integer) 7 127.0.0.1:6379> get k1 "v100abc"
3.3.4、返回key的长度
127.0.0.1:6379> strlen k1 (integer) 7
3.3.5、不存在的key设置值,如果存在,不做任何操作
127.0.0.1:6379> setnx k1 v2000 (integer) 0 127.0.0.1:6379> setnx k66 v2000 (integer) 1
3.3.6、mset一次设置多个值
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 OK 127.0.0.1:6379> keys * 1) "k2" 2) "k1" 3) "k3
3.3.7、一次获取多个值
127.0.0.1:6379> mget k1 k2 k3 1) "v1" 2) "v2" 3) "v3"
3.3.8、msetnx一次设置多个不存在的key的值,原子性,有一个失败,全部失败
127.0.0.1:6379> msetnx k11 v11 k12 v12 k1 v23 (integer) 0
3.3.9、数据结构
String的数据结构为简单的动态字符串(Simple Dynamic String,缩写SDS)是可以修改的字符串,最大长度512M;
3.4、Redis列表(List)
3.4.1、简介
单键多值;
Redis列表是简单的字符串列表,安装插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际是个双向链表,对两端的操作性很高,通过所有下表的操作中间的节点 性能会较差。
3.4.2、列表常用命令
lpush——从左边加
127.0.0.1:6379> lpush k1 v1 v2 v3 (integer) 3
lrang——从左边取值
127.0.0.1:6379> lrange k1 0 -1 1) "v3" 2) "v2" 3) "v1"
从左边取一个值:
127.0.0.1:6379> lpop k1 "v3"
从右边取一个值:
127.0.0.1:6379> rpop k1 "v1"
插入新值:
127.0.0.1:6379> linsert k1 before v2 new (integer) 5 127.0.0.1:6379> lrange k1 0 -1 1) "v4" 2) "v3" 3) "new" 4) "v2" 5) "v1"
3.4.3、数据结构
3.5、Redis集合(Set)
Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动重排的,当你需要存储一个列表数据,又不希望出现重复数据时候,set是一个很好的选择;
Redis的Set是string类型的无序集合,它底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是0(1);
添加
127.0.0.1:6379> sadd k1 1 2 3 (integer) 3 127.0.0.1:6379> smembers k1 1) "1" 2) "2" 3) "3"
返回元素个数
127.0.0.1:6379> scard k1 (integer) 3
数据结构
Set数据结构是dict字典,字典使用哈希表实现的。
3.6、Redis哈希
加数据
127.0.0.1:6379> hset user:1001 id 1 (integer) 1 127.0.0.1:6379> hset user:1001 name zhang (integer) 1
取数据
127.0.0.1:6379> hget user:1001 id "1" 127.0.0.1:6379> hget user:1001 name "zhang"
数据结构
3.7、有序集合Zset
Redis有序集合,与普通集合set非常相似,是一个没有重复元素的字符串集合,有序集合每个元素都关联了一个评分,这个评分用来从低到高排序成员集合,集合成员是唯一的,评分可以重复,
添加zset集合
127.0.0.1:6379> zadd topn 200 java 300 php 400 c++ (integer) 3
取值
127.0.0.1:6379> zrange topn 0 -1 1) "java" 2) "php" 3) "c++"
取值的时候带评分
127.0.0.1:6379> zrange topn 0 -1 withscores 1) "java" 2) "200" 3) "php" 4) "300" 5) "c++" 6) "400"
四、Redis配置文件
只支持bytes,不支持bits;
大小写不敏感;
NETWORK——是否支持远程连接
# bind 192.168.1.100 10.0.0.1 # listens on two specific IPv4 addresses # bind 127.0.0.1 ::1 # listens on loopback IPv4 and IPv6 # bind * -::* # like the default, all available interfaces
注释本地连接,
#bind 127.0.0.1 -::1
protected-mode——保护模式,修改为no,支持远程访问
protected-mode no
port 端口号
port 6379
timeout 超时时间
timeout 0 #0永不超时
tcp-keepalive 连接检测时间
tcp-keepalive 300
loglevel 日志级别
# debug (a lot of information, useful for development/testing) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) loglevel notice
五、Redis的发布和订阅
Redis的发布和订阅(pub/sub)是一种消息的通信模式,发送者pub发送消息,订阅者sub接收消息;
Redis客户端可以订阅任意数量的频道;
用命令演示发布和订阅:
打开一个客户端订阅channel1:
[root@localhost bin]# ./redis-cli 127.0.0.1:6379> SUBSCRIBE channel1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "channel1" 3) (integer) 1
打开另外一个客户端,发送消息:
[root@localhost bin]# ./redis-cli 127.0.0.1:6379> publish channel1 hello (integer) 1 127.0.0.1:6379>
查看订阅的客户端:
[root@localhost bin]# ./redis-cli 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
六、Redis的新数据类型
6.1、Bitmaps
添加数据
127.0.0.1:6379> setbit users:20230101 1 1 (integer) 0 127.0.0.1:6379> setbit users:20230101 6 1 (integer) 0 127.0.0.1:6379> setbit users:20230101 11 1 (integer) 0 127.0.0.1:6379> setbit users:20230101 15 1 (integer) 0 127.0.0.1:6379> setbit users:20230101 19 1 (integer) 0
6.2、HyperLogLog
基数统计算法;基数就是不重复元素
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 "c++" (integer) 1
统计
127.0.0.1:6379> pfcount program (integer) 3
6.3 Geospatial
地理信息坐标,二维坐标;
添加信息
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai (integer) 1
取值:
127.0.0.1:6379> geopos china:city shanghai 1) 1) "121.47000163793563843" 2) "31.22999903975783553"
7、Jedis操作Redis
idea创建一个Meav工程:
引入依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>Jadis_Redisdemo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.2.0</version> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> </project>
创建一个包
创建测试类
添加地址
package com.ziguang.zs; improt redis.clients.jedis.Jedis; public class jadisDemo1 { public static void main(String[] args){ Jedis jedis = new Jedis(host:"192.168.43.25",prot:6379); String value = jedis.ping(); System.out.println(value); } }
八、Redis的事务和锁
8.1、事务的执行与结束
Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行,事务在执行过程中,不会被其他客户端发送来的命令请求打断。
Redis事务的主要作用就是串联多个命令防止别的命令插队。
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
discard放弃组队
127.0.0.1:6379> multi OK 127.0.0.1:6379(TX)> set key3 value3 QUEUED 127.0.0.1:6379(TX)> set key4 value4 QUEUED 127.0.0.1:6379(TX)> discard OK
组队过程中,有错误都不执行;
组队中没有错误,执行中有错误,有错误的不执行,没错误的执行;
8.2、事务的冲突
悲观锁:每次操作之前先上锁,比如行锁,表锁,读写锁;都是在操作之前先上锁;
乐观锁适用于多读的数据类型;
8.3、Redis事务的三个特性
单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行、事务在执行过程中,不会被其他客户端发送来的命令请求所打断;
没有隔离级别的概念:队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何命令都不会被实际执行;
不保障原子性:事务中如果有一条命令执行是吧,气候的命令任然会被执行,没有回滚;
九、Redis持久化
Redis提供2种不同形式的持久化方式
RDB(Reids DataBase)
AOF(Append Of File)
9.1、RDB
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot快照,它恢复时是将快照文件直接读到内存里;
数据持久化在配置文件中的位置:
dbfilename dump.rdb rdb-del-sync-files no # The working directory. # # The DB will be written inside this directory, with the filename specified # above using the 'dbfilename' configuration directive. # # The Append Only File will also be created inside this directory. # # Note that you must specify a directory here, not a file name. dir ./
数据持久化规则,20秒内有3个数据变换就进行一次持久化
# save 300 100 # save 60 10000 save 20 3
持久化存储保存的位置,其中dump.rdb 就是持久化数据
[root@localhost bin]# ls dump.rdb redis-check-aof redis-cli redis-server redis-benchmark redis-check-rdb redis-sentinel
9.2、Redis数据恢复
先添加数据
127.0.0.1:6379> set a a OK 127.0.0.1:6379> set b b OK 127.0.0.1:6379> set c c OK 127.0.0.1:6379> set d d OK 127.0.0.1:6379> set e e OK
备份持久化文件
[root@localhost bin]# cp dump.rdb dump.rdb.bak
删除持久化文件
[root@localhost bin]# rm dump.rdb
rm: remove regular file ‘dump.rdb’? y
重启redis
[root@localhost redis-6.2.1]# systemctl restart redis
查看数据
[root@localhost bin]# ./redis-cli 127.0.0.1:6379> keys * (empty array)
恢复文件
[root@localhost bin]# cp dump.rdb.bak dump.rdb
重启数据库,直接杀进程,用命令重启
[root@localhost redis-6.2.1]# systemctl restart redis
查看数据
[root@localhost bin]# ./redis-cli 127.0.0.1:6379> keys * 1) "e" 2) "d" 3) "c" 4) "b" 5) "a"
9.3、AOF
AOF(Append Only File)
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),redis启动之初会读取该文件重构新建数据。
在配置文件中的位置,改为yes
appendonly yes
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
重启redis查看,多个aof文件
[root@localhost bin]# ls appendonly.aof dump.rdb.bak redis-check-aof redis-cli redis-server dump.rdb redis-benchmark redis-check-rdb redis-sentinel
RDB和AOF同时开启,系统默认读取AOF文件
AOF文件的损坏修复
修改aof文件,末尾加一行hello,重启报错
[root@localhost bin]# vi appendonly.aof
set
$1
c
$1
c
hello
修改文件
[root@localhost bin]# redis-check-aof --fix appendonly.aof 0x 68: Expected prefix '*', got: 'h' AOF analyzed: size=111, ok_up_to=104, diff=7 This will shrink the AOF from 111 bytes, with 7 bytes, to 104 bytes Continue? [y/N]: y Successfully truncated AOF
AOF持久化流程
AOF优势
AOF劣势
RDB和AOF用哪个
https://cvzhanshi.blog.csdn.net/article/details/119731027