Redis
1.基础配置
-
版本
- 3.x之前不支持分布式安装
- 3.x之后支持分布式安装
-
优缺点
-
单个redis容易发生单点故障,一台服务器很难处理大量内存.
-
redis可用的存储空间有限,即使是打野不能用
-
配置文件
./redis/redis.conf
名称 | 作用 | 行号 | 注意事项 |
---|---|---|---|
daemonize no | 设置为守护线程 | 136 | yes:守护线程 |
bind 127.0.0.1 | 可以连接的地址 | 69 | 注释掉设置为远程登录 |
port | 默认端口号 | 93 | |
pidfile pid文件地址 | 设置pid的文件 | 159 | 只有设置为守护线程才生效 |
logfile 日志文件 | 设置日志保存文件 | 172 | 设置为守护线程默认为:/dev/null |
datqabases 16 | 设置存储库数量 | 187 | 默认16个 |
save 10 1 | 10秒钟有1个key持久化到硬盘 | 219-221 | 三个条件满足其中一个就持久化 |
rdbcompression yes | 本地存储数据是否进行压缩 | 252 | yes:开启默认开启 |
dbfilename 持久化文件 | 设置持久化备份的库文件 | 254 | |
dir 指定数据存储位置 | 指定数据库保存的位置 | 264 | 默认redis目录下 |
requirepass foobared | 设置密码 | 508 | 默认注释(redis3.0之后必须设置),通过"-a 密码"进行连接,明文书写即可,java通过auth连接 |
maxclients | 设置并发线程连接数 | 540 | 默认注释没有限制 |
maxmemory | 指定Redis最大内存 | 567 | 默认注释,默认值256M(建议1g分配256-512) |
- LRU
搜索lru进行配置,只需要配置一个模式
名称 | 作用 | 注意事项 |
---|---|---|
volatile-lru | 删除最不常用的超时数据 | 后面配置超时时间 |
allkeys-lru | 查询所有key中最近最不常使用的数据进行删除 | 常被配置的模式 |
volatile-random | 随机删除超时数据 | 后面配置超时时间 |
allkeys-random | 查询所有数据后随机删除 | |
volatile-ttl | 查询所有超时数据,排序后删除 | 后面配置超时时间 |
noeviction | 不进行处理,内存溢出时报错 | 默认配置 |
volatile-lfu | 在所有超时数据中驱逐使用频率最少的键 | 4.0新功能 |
allkeys-lfu | 在所有键中驱逐使用频率最少的键 | 4.0新功能 常见配置 |
2.redis命令
1.共有命令
操作成功几个数据返回几
-
查看所有key
keys *
-
删除key
del x [y..]
-
检测是否含有key
exists x [y..]
-
清除时间
-
设置清除时间
-
秒
expire x 10
-
毫秒pexpire x 1000
-
-
查看清除时间
-
返回值
返回值 作用 注意事项 -1 永久有效 -2 无效 >0 剩余时间 -
秒
ttl x
-
毫秒
pttl x
-
-
设置为永久有效
persist x
-
-
返回随机KEY[不常用]
random key
-
重命名KEY
rename x y
-
查看数据类型
type x
-
序列化
dump x
2.String
最大的key为512mb,不会发生编码异常,在客户端编解码
用途:用户限制登录
-
set增加数据
可以覆盖之前的数据和类型
set str 10
-
mset批量增加
mset str1 10 str2 x str3 20
-
查看一个数据
get string
key sitring:?[1,2]
-
批量查看
mget str1 str2 str3
-
getrange截取
getRange str n1 n2
-
getset返回之前的值,设置新值
getset str 15//输出nil getset str 10//输出10
-
strlen长度
strlen str
-
append判断追加
key存在时追加值,key不存在时赋值
append str 10
-
setnx 判断赋值
key存在时不进行操作,key不存在时赋值
setnx str 10;
-
加减操作
只能对String类型的数值进行操作,以0开头的数值视为字符串,不书写n时为加减1,0不存在时从0开始计算
-
加1
incr string
-
减1
desr string
-
自增n
incrby str n;
-
自减n
decrby str n;
-
添加一个n秒的临时数据
setex str n value
3.Hash
存储对象,类似于HashMap
-
hset添加对象的一个属性
hset user:1 id 1
-
hmset批量添加对象的多个属性
hmset user:1 id 1 name zhangsan
-
hget 获取对象的一个属性值
gset user:1 id
-
hmset批量获取对象的多个属性值
hgset user:1 id name
-
hgetall获取对象的所有属性名和属性值
hgetall user:1
-
hdel删除对象的一个或多个属性
hdel user:1 id [user]
-
hsetnx存在属性时不操作,不存在属性时添加
hsetnx user:1 id 1
-
hexists检测是否存在属性
返回值存在个数
hexists user:1 id [name...]
4.List
用途:做流程
类似于linkedList
-
lpush(从左侧(头部)开始添加,最先添加的是尾部最后一个)
lpush friend x [x] [x]
-
rpush(从尾)
rpush friend x [x] [x]
-
rpushx:最右侧添加(不受1/2的影响)
rpushx key x
-
lpushx:最左侧添加(不受1/2的影响)
lpushx key x
-
lrange:查看n1-n2的值(可以实现分页)
负数代表从后开始数第几个,例如-1代表最后一个
lrange friend n1 n2
-
lpop:从头部弹出,弹出就没了(删除)
lpop friend
-
rpop:从尾部弹出
rpop friend
-
brpop:从头部弹出,没值的话等待1000秒,有值就弹出(等待时代表全部弹出,这个key就被删除了,需要重新赋值)
blpop key 1000
-
blpop:从尾部弹出,如果在1000秒之后有值就弹出
blpop key 1000
-
rpoplpush:从friend1右侧弹出从friends头部插入
rpoplpush friend1 friend2
-
lset:更改下标为n的key的值为x
lset key n x
-
linset:将x插入下标为n的key的前面或后面
linsert key before|after n x
-
llen:长度
llen key
-
lindx:显示下标为n的key值
lindex key n
5.Set
类似于hashtable:无序不重复
-
sadd:添加数据
sadd key a b c
-
scard:获取数据数
scard key
-
smembers:获取所有数据
smembers key
-
sismember:查询是否存在a数据
sismember key a
-
srandmember:返回集合中一个或n个数据
srandmember key [n]
-
srem:删除key中的一个或多个数据
srem key a [b]
-
spop:随机删除key中一个或n个数据并返回删除的值
spop key [n]
-
smove:将一个数据移动到另一个key
将key1中的a移动到key2中
smove key1 key2 a
-
差集:
-
sdiff:查询交集之外的不相同的数据
sdiff key1 key2 [key3]
-
sdiffstore:脚趾之外的不同的数据复制到key中
sdiiffstore key key1 key2 [key3]
-
-
交集:
-
sinter:查询共有数据
sinter key1 key2 [key3]
-
sinterstore:共有数据并复制到key中
sinterstore key key1 key2 [key3]
-
-
并集:
-
sunion:查询所有数据
sunion key1 key2 [key3]
-
sunionstore:所有数据并复制到可以中
sunionstore key key1 key2 [key3]
-
6.Zset
用途:排行榜
有序集合且不允许重复,但是通过一个double分数来排列顺序,分数可以重复
-
zadd:增加一个或多个数据
zadd key 分数 a [分数 b]
-
zcound:查看分数1-分数2的成员个数
zcard key 分数1 分数2
-
zrange:通过从低到高查看下标0-n之间的数据
zrage key 0 n
-
zrevrange:通过从高到第查看下标0-n之间的数据
zrevrange key 0 n
-
zrem:删除数据
zrem key a [b]
-
zremrangebybank:删除下标0-n之间的数
zremrangebybank key 0 n
-
zremrangebyscore:删除分数之间的数
zremrangebycore key 分数1 分数2
3.redis操作
1.发布订阅
-
作用:
订阅频道,从而接收数据
-
subscribe:订阅频道:处于接收状态
subscribe 频道 [频道1]
-
publish:向指定频道发送信息
publish 频道 信息
-
unsubscribe:退订频道
unsubcribe
-
punsubscribe:退订所有频道
punsubscribe
2.多数据库
-
select:切换数据库
[0-15]默认16个数据库
select n
-
move:移动数据到另一个数据库
move key n
-
flushdb:删除当前数据库的所有key
flushdb
-
flushall:删除每个数据库的所有key
flushall
3.事务
用途:一组行为执行时:秒杀活动
-
multi:开始事务
multi
-
exec:执行
数据出错:只有出错的语句不会被执行
语法错误(报告错误):都不会被执行,会自动回滚
exec
-
discard:回滚(放弃执行)
discard
-
watch:
- 监视一个或多个key,如果这个key在事务期间被更改,那么当
exec
时就会回滚,并取消监视 - 在
multi
之前执行,如果执行exci
或discard
就会自动取消监视
watch key [key]
- 监视一个或多个key,如果这个key在事务期间被更改,那么当
-
unwatch:取消所有监视
unwatch [key] [key]
4.持久化
1.RDB
-
基础知识:
- 默认开启
- 定期将内存中的数据做成快照保存在磁盘中
- 默认存储在redis目录下,名为dump.rdb
-
优缺点
- 优点:保存和读取数据都很快
- 缺点:
- 小机器不适合做快照
- 在非正常关机时无法保存
-
快照条件:
- 执行shutdown正常关闭时
- 执行flushall删除所有key时
- 在指定时间间隔内
- 执行save命令
-
恢复rdb:
将dump.rdb文件拷贝到redis下的bin目录即可
2.AOF
-
基础知识:
- 执行操作之后会将操作写在日志中,如果出现问题可以回滚
- 每做一次写操作都会,就会将操作追加到appendoly.aof中,当redis重启时就会重新读取整个数据库
-
启动AOF,修改配置文件:
-
启动AOF:699默认no
appendonly yes
-
指定存储文件名:703
appendfilename "appenonly.aof"
-
指定跟新日志条件:728默认注释
appendfsync 条件
- always:写操作一次就写入一次:
- everysec:每秒钟写入一次:性能和持久化居中
- no:完全依赖os,性能最好,持久化没保证
-
配置重写机制
当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。一般都设置为3G,64M太小了。
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
-
-
恢复AOF
-
直接复制到bin目录下 -
通过命令
redis-check-aof --fix appendonly.aof
-
5.数据一致性
1.实时同步
数据库与redis
@cacheable:查询时使用,注意Long类型需转换为String类型,否则会抛异常
@CatchPut:更新时使用,使用此注解,一定会从DB上查询数据
@CacheEvicat:删除时使用;
@Caching:组合用法:
2.异步队列
消息中间件:kafka
3.主从复制
可以使用阿里插件:canal也可以用下列方法
-
修改从服务器redis配置文件
- port:6380(重新修改端口号):此端口是从服务器的端口号
- slaveof 127.0.0.1 6379(指定主服务器和端口号用于连接主服务器)
-
或者使用命令切换主从服务器
- slaveof ip地址 端口号 变回从服务器:只能进行查
- slaveof on one 变回主服务器
-
slavef 查询新的master
slaveof new master
4.其他
- udf自定义函数
- 脚本
5.相关知识点
-
数据库穿透:
可能查询到的是null数据,null数据不会写入redis缓存,而是返回查询失败,更多的人访问最后导致宕机,因此可以设置如果数据库查询到的是null的话就添加key但是值是null;
-
雪崩:
缓存集中在同一时间段失效,导致大量用户进入数据库查询产生数据穿透
- 分析用户行为,找到合适的时间点失效
- 加锁或者队列
- 缓存预热
-
热点key:
4.Cluster集群
1.基础知识
-
无中心,无需连接所有的服务器
-
必须要3master+3slaveof才能配置成集群
-
共有0-16383共16384个hash曹,个人服务器均分
-
容错性(投票):当一个服务器在半数以上的服务器无法连接时视为当前无服务挂掉
-
节点分配:A(0-5460)B(5461-10922)C(10923-1638)
如果增加新的服务器则分别从ABC的前面出去一部分最后达成均分
-
真集群和假集群以下为假集群的创建规则
2.搭建流程
1.修改配置文件
-
复制配置文件
-
创建Redis节点安装总目录
mkdir /usr/local/redis_cluster
-
创建Redis节点安装目录(复制5份redis配置文件(7001-7005))
cp `~/redis.conf /usr/local/redis_cluster/7001/
-
-
修改配置文件
参数 作用 行号 #bind ip地址 注释 bind IP
:不设置地址69 protected-mode no 不允许公网访问(真集群设置为允许) 88 port 7001 修改端口号 92 daemonise yes 允许后台运行 136 pidfile /var/run/redis-7001.pid 修改pid进程文件.默认以pid命名名称 158 logfile 存放地址/redis.log 修改日志文件地址,可不修改 171 dir 存放地址 修改数据文件存放地址,以端口号为目录名区分,可不修改 263 #requirepass redisyangtuo 不设置密码 507 cluster-enable yes 启用集群 832 cluster-config-file node-7001.conf 修改节点的配置文件 840 cluster-node-timeout 15000 配合集群节点的超时时间,使用默认 846 -
启动并查看
-
启动5份redis
redis-server /配置文件
-
查看是否启动
ps -ef |grep redis
-
关闭reids
redis-cli -p 7001 shutdown
-
2.安装软件
1.ruby
redis-trib.rb的依赖
建议编译安装,而不是下列方法
yum -y install ruby ruby-devel rubygams rpm-build
2.rvm
用于更新ruby,官方文档:https://www.rvm.io/rvm/install
stable:最新版 master:最新开发版
-
安装rvm官方的两个gpg秘钥
-
标准方法(经常失败:原因未知)gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
-
替代方法
curl -sSL https://rvm.io/mpapis.asc | gpg --import - curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -
-
-
安装rvm
-
标准安装\curl -sSL https://get.rvm.io | bash -s stable
-
使用ruby安装rvm
\curl -sSL https://get.rvm.io | bash -s stable --ruby
-
-
检验安装情况
find / -name rvm -print
-
加载配置文件
-
普通加载
source /usr/local/rvm/scripts/rvm
-
设置环境变量(官方脚本:全局)source /etc/profile.d/rvm.sh
-
-
升级rvm
rvm get stable
-
查看ruby版本
rvm list known
-
安装最最新版ruby
rvm install 2.6.3
-
使用一个ruby版本
rvm use 2.6.3
-
设置默认ruby版本
rvm use 2.6.3 --default
-
查看ruby版本
ruby --version
-
安装redis与ruby整合工具
gem isntall redis
3.创建启动
-
创建redis_cluster
-
3.0-4.0
redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.1:7005
-
5.0:不需要安装ruby
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
先出的结果为主,输入yes
-
-
连接reids
-c:连接集群 -p:访问7001
redis-cli -h 127.0.01 -c -p 7001
-
查看节点测试:redis命令
info replication
-
查看所有节点信息:redis命令
每个节点都有一个id,用节点来对应,可以更改端口号
主用来set,从用来get,若果set就会跳到get中
cluster nodes
4.集群管理
-
添加单个集群
add-node
-
删除单个集群
del-node
-
删除全部集群
- 关闭所有集群
- 删除nodes-port.conf配置文件
- 重建集群
4.相关方法
-
新建对象
@Autowired private RedisTemplate<String,String> redisTemplate; public String getString(String username) { ValueOperations<String, String> string = redisTemplate.opsForValue(); if(redisTemplate.hasKey(username)) {//redis中有,直接输出 System.out.println("在redis中查找:"); return string.get(username); } else {//redis中没有数据,在mysql中查找后赋值(模拟),并输出 String age="15"; string.set(username, age); System.out.println("在mysql中查找:"); return age; } }
-
语法规律
公用redis语法对应redisTemplate静态方法
私有redis语法对应redisTemplate.ospFor***()
7.java操作
1.jedis直连
-
pom.xml
jedis/Redisson
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
-
连接redis
Jedis jedis = new Jedis("111.230.23.216",6379);
-
输入密码
jedis.auth(密码);
-
检测连通性
输出ping=pong时连接成功
String ping = jedis.ping();
2.redis池
1.配置池
不配置的话,默认最大连接数和空闲数是8
-
新建对象
redisPoolConfig rfg = new redisPoolConfig();
-
设置最大连接数
rfg.setMaxTotal(5);
-
设置最大空闲数
rfg.setMaxIdle(1);
2.连接池
-
jedisPool
JedisPool jp = new JedisPool(rfg,111.230.13.216[,连接时间,密码]);
-
获取jedis
Jedis jedis = jp.getResource();
-
输入密码jedis.auth("密码");
3.工具类
可以再写别的内容:例如添加key或者设置过期时间
public class RedisPoolUtil {
static private JedisPool jp;
static {
//1.配置库
JedisPoolConfig jpc = new JedisPoolConfig();
jpc.setMaxTotal(5);
jpc.setMaxIdle(1);
String path = "111.230.13.216";
int port = 6379;
jp = new JedisPool(jpc,path,port);
}
public static Jedis getJedis() {
Jedis jedis = jp.getResource();
return jedis;
}
public static void close(Jedis jedis) {
jedis.close();
}
}
6.SpringMVC
1.添加依赖
-
pom.xml
<!-- redis客户端:jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <!-- SpringDate-redis:整合spring和redsis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.4.RELEASE</version> </dependency>
-
版本对照表
必须对应特定的版本,否则就会报错,可以
ctrl
+鼠标点击spring-data-redis
点击查看对应版本spring-data-redis版本 jedis版本 备注 1.5.2.RELEASE 2.7.3 1.6.0.RELEASE 2.7.2 2.7.3 1.6.2.RELEASE 2.8.0 1.8.1.RELEASE 2.9.0 1.8.4.RELEASE 2.9.0
2.整合redis
sprng-redis.xml配置文件
<!-- 1. 配置连接池信息 -->
<bean id="jedisPoolConfig"
class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="50"></property>
<property name="maxIdle" value="5"></property>
</bean>
<!-- 2.redis连接池工厂方法 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="111.230.13.216"></property>
<property name="port" value="6379"></property>
<property name="poolConfig" ref="jedisPoolConfig"></property>
</bean>
<!-- 3.redisTemplate模板:类似工具类 -->
<bean id="redisTmplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
3.修改序列化
1.修改序列化
//<bean id="redisTmplate" class="org.springframework.data.redis.core.RedisTemplate">
//<property name="connectionFactory" ref="jedisConnectionFactory" />
<!--String类型-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
//</bean>
2.使用StringRedisTmplate
- 公用方法在redisTmplate中
- 私有方法在redisTmplate.ospValue/Hset