这是我参与更文挑战的第18天,活动详情查看: 更文挑战
这里含括了基本命令和进阶命令和集群的知识。
dokcer安装redis
docker pull redis:latest
docker 启动 redis
docker run -p 6379:6379 --name redis -v /opt/docker_redis/redis.conf:/etc/redis/redis.conf -v /opt/docker_redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes --requirepass 123456
命令说明
-p 6379:6379 端口映射:前表示主机部分,:后表示容器部分。
--name redis 指定该容器名称,查看和进行操作都比较方便。
-v 挂载文件或目录 :前表示主机部分,:后表示容器部分。
-d redis 表示后台启动redis
redis-server /etc/redis/redis.conf 以配置文件启动redis,加载容器内的conf文件,最终找到的是挂载的目录/usr/local/docker/redis.conf
--appendonly yes 开启redis 持久化
--requirepass 123456 设置密码为123456
进入: docker exec -it redis /bin/bash
进入: docker exec -it redis /bin/bash
redis-cli -p 6379
获取密码:config get requirepass
输入密码: auth 123456
String ::
set k v , get k , EXISTS k, move k 1(当前库), keys * , flushdb
EXPIRE k time,ttl k(查看剩余时间),type k(查看类型)
object encoding key(查看底层数据类型 embstr->44长度以内, int,raw>45)
原因cpu缓存行(redisobject16byte+4bytes(flags+colle+len)+44bytes)
strlen key(str长度)
APPEND k"hello", STRLEN k, GETRANGE k 0 1(获取0-1的字符)
incr k 加1,decr k减1,INCRBY k num(加num),替换:
STERANG k 1 x 从1位置修改=substr
setnx (set with exist存在会失败,分布式锁) , setex 设置过期时间
mset k1 v1 k2 v2 ... mget k1 k2 ..
对象:
set user:1 {name:zhangsan,age:3} 设置一个user:1对象
mset user:1:name zhangsan user:1:age 2
mget user:1:name user:1:age
getset k v 不存在,返回nil,存在更新
List ::
可以实现:堆、栈、队列、阻塞队列
LPUSH list one 插入头部
LPUSH list two
LRANGE list 0 -1 全部值
LRANGE list 0 1 倒着获取
RPUSH list right 右边插入,插入到了尾部
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
3) "right"
127.0.0.1:6379> LPOP list 移除头
"two"
127.0.0.1:6379> RPOP list 移除尾
"right"
127.0.0.1:6379> LRANGE list 0 -1
1) "one"
127.0.0.1:6379> Lindex list 0 获取具体某一个值
"one"
127.0.0.1:6379> Llen list 获取list长度
(integer) 1
###################################################
移除指定的值
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "one"
127.0.0.1:6379> lrem list 1 2 移除一个2的值
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "one"
###################################################
trim 修剪
Ltrim list 0 1 截取指定长度
rpopLpush 移除最后一个元素到新的list
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> rpopLpush list mylist
"one"
127.0.0.1:6379> Lrange mylist 0 -1
1) "one"
127.0.0.1:6379> Lrange list 0 -1
1) "two"
127.0.0.1:6379> EXISTS list 返回0不存在
Lset list 0 one1 设置list0的索引为one1,不存在会报错
Linsert list before "two" "two1" 在某个值前面或者后面插入某个值 after
127.0.0.1:6379> Lrange list 0 -1
1) "two"
127.0.0.1:6379> Linsert list before "two" "two1"
(integer) 2
127.0.0.1:6379> Lrange list 0 -1
1) "two1"
2) "two"
###################################################
set::
sadd set "one" 无序不重复集合
sadd set "two"
127.0.0.1:6379> SMEMBERS set 查看
1) "two"
2) "one"
SISMEMBER set "one" 是否存在
scard set 获取个数
srem set one 移除某一个元素
SRANDMEMBER set 随机获取一个元素
SRANDMEMBER set n 随机获取指定元素
spop set 随机删除某个元素
smove set myset "one" 把one元素从set移到myset中,myset不存在则创建
集合:
127.0.0.1:6379> SMEMBERS set
1) "one"
2) "two"
127.0.0.1:6379> SMEMBERS myset
1) "one"
SDIFF set myset 差集
SINTER set myset 交集 共同好友
SUNION set myset 并集
###################################################
Hash:: 头插法解决冲突
Map集合 , K V
hset hash ransong shuaige
hget hash ranosng
hmset hash k1 v1 k2 v2 (map)
hmget hash k1 k2
hdel hash k 删除
hlen k 查询数量
HEXISTS hash k 是否存在
HGETALL hash 获取所有k v
hkeys hash 所有k
hvals hash 所有v
incr decr
HINCRBY hash age 1 -1
hsetnx hash k v 存在报错
应用:变更数据 user name user , 经常变动的信息,对象的信息
###################################################
Zset 有序无重复集合
zadd salary 2500 A
zadd salary 3000 B
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf 升序
1) "A"
2) "B"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf 2500 withscores 详细信息
1) "A"
2) "2500"
127.0.0.1:6379>
127.0.0.1:6379> ZREVRANGE salary 0 3000 降序
1) "B"
2) "A"
zrange salary 0 -1 获取所有
zrem salary B 移除某个元素
ZCARD key返回key的有序集元素个数。O(1)
特殊数据类型:
geosptial 地理位置,附近的人,打车距离,南北两极无法添加,程序添加
geoadd china:city 116.40 39.90 beijing 经度先维度后去百度查一下
geoadd china:city 116.40 39.90 shanghai
geopos china:city beijing
geopos china:city shanghai
GEODIST china:city beijing shanghai km 北京到重庆距离km
我附近的人,获取所有附近的人,定位,通过半径来查询
GEORADIUS china:city 110 30 500 km 经度维度 半径 ,以点为中心,半径查找
withdist withcoord根据经度获取维度 count数量
GEORADIUSBYMEMBER china:city beijing 1000 km 以beijing为中心的1000KM
(指定元素定位)
GEOHASH 以hash表示经度维度的字符串
ZRANGE china:city 0 -1 所有
ZREM china:city beijing 移除某个
HYperloglog 基数 一个数据集不重复的元素的个数
网站浏览计数
优点:占用内存小
PFadd mykey a b c d
PFCOUNT mykey
PFadd mykey2 e f g
PFMERGE mykey3 mykey myke2 合并
Bitmaps
位存储
统计用户信息,活跃,不活跃,打卡,签到
setbit sign 0 1
setbit sign 1 0
setbit sign 2 0
getbit sign 2
统计打卡的天数,或者指定天数
bitcount sign
bitcount sign 0 5
事务
redis单条命令保存原子性的,事务是不保证原子。
开启事务 命令入队 执行事务 取消事务DISCARD,命令不会执行
Multil ... exec
127.0.0.1:6379> Multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) "v2"
命令出错,事务命令不会执行。
运行出错,只有运行命令不能执行,其他正常执行(对字符串incr)
乐观锁:
watch 监控
set money 100
set out 0
watch money (防止其他线程更改money,如果出错unwatch重新watch
multi
DECRBY money 20
INCRBY out 20
exec
springboot整合
jedis直连,多个线程操作不安全 jedis pool BIO
letture:采用netty,实例多个线程共享
配置文件
配置大小写不敏感
多个配置信息
daemonize yes 以守护进场开启
loglevel notice (通知)日志级别
数据库的数量默认16
持久化
save 900 1 900s内,至少一个key修改,进行持久化
save 300 10
save 60 10000 60s,10000key修改,进行持久化
rdbcompression yew 压缩rdb文件,消耗cpu资源
rdbchecksum yes 保存rdb错误校验
dbfilename dump.rdb (条件:save或者flushdb或者断连,使用:启动就check 5s一次 save 5 1)
kill -9 粗暴退出会导致key没有
maxclients 1000 设置最大客户端连接
maxmemory bytes
maxmemory-policy noeviction 内存上线策略lru,默认随机lru
appendonly no aof配置,默认不开启
appendfilename "appendonly.aof"
appendfsync everysec 1s一次
生产中持久化两种方式都要使用
rdb
条件:save或者flushdb或者断连,使用:启动就check
优点:大规模数据恢复 对数据完整性要求不高
缺点:1.fork进程,占用内存空间 2.有一定时间,如果宕机,数据丢失。
aof(记录所有命令)
fork进程,生产临时aof文件
条件:每秒或者退出 使用:启动读取
vim appendonly.aof 全是命令文件
redis-check-aof --fix appendonly.aof (aof被修改路,执行不了,修复aof文件 )
(都要打开 : 可能会降低性能)
建议rdb 只保留save 60 10000
aof:aof重写基础大小默认64M改为5G以上
主从复制:(自动执行)减少重写带来的IO,如果主从同时宕机,会丢失10多分钟数据,启动脚本比较
载入最新脚本(默认执行aof),微博使用这种架构。
redis发布订阅
subscribe ransong 订阅
第二个redis 客户端
PUBLISH ransong handsome 发布消息
退订:
主从:
只配置从库
cp redis.conf redis redis79.conf
cp redis.conf redis redis80.conf
cp redis.conf redis redis81.conf
79:端口6379 守护进程打开 logfile:"6379.log" dbfilename dump6379.rdb
80:port 6380 daemonize yes ,pidflie /var/run/redis_6380.pid
logifle:"6380.log" dbfilename dump6380.rdb
81:port 6381 daemonize yes ,pidflie /var/run/redis_6381.pid
logifle:"6381.log" dbfilename dump6381.rdb
redis-server redis79.conf
redis-server redis80.conf
redis-server redis81.conf
查看 ps -ef |grep redis
info replication
配置从:6380
SLAVEOF 127.0.0.1 6379 121.199.65.124 6379(重启会变回从机)
config set masterauth 123456
info replication
通过keys * 查看,默认从库只能读取
slaveof no one 变成主机
哨兵:(多哨兵模式)
1.
vim sentinel.conf
sentinel monitor myredis 127.0.0.1 6379 1 (myredis监控name,1代表主机挂投票)
2.启动
redis-sentinel sentinal.conf
3.master
shutdown
4.自动切换
5.主机启动, 变成从机 +sdown slave 127.0.0.1:6379
缺点:在线扩容麻烦
分布式锁:异常、宕机(释放锁)、(哪个线程加锁,哪个线程解锁,传参id=UUID)
续命:
Rlock redissonLock = redisson.getlock(key);
redissonLock.lock()阻塞非公平锁,getFailLock公平锁;
非阻塞,没拿到锁立即返回
tryLock(2,10,SENDS) 等待2s中,最长等待10s,防止死锁,释放锁
...
finally {
redission.unlock();
}
<!--分布式锁 https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.13.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
缓存穿透,查不到(设置null缓存,布隆过滤器)和雪崩(多级缓存)
缓存击穿,查的多,过期:过期时间分散设置,热点数据不过期
redis-cli -a 123456 --cluster create --cluster-replicas 1 192.168.1.1:8001
192.168.1.1:8002 192.168.1.1:8003 192.168.1.1:8004 192.168.1.1:8005
192.168.1.1:8006
cluster info
cluster nodes
cluster keyslot k1
8001:set k1 guojia (重定向)Redirected to slot 12706 located 192.168.1.102:8003
8003:get k1 ( % 16384) rediscluster优化crc16 key & (16384 -1)
❤️❤️❤️❤️
非常感谢人才们能看到这里,如果这个文章写得还不错,觉得有点东西的话 求点赞👍 求关注❤️ 求分享👥 对帅气欧巴的我来说真的 非常有用!!!
如果本篇博客有任何错误,请批评指教,不胜感激 !
文末福利,最近整理一份面试资料《Java面试通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:GitHub github.com/Tingyu-Note…,更多内容关注公号:汀雨笔记,陆续奉上。