一、Redis
1、在docker 中打开redis
docker exec -it myredis /bin/bash
2、打开客户端,登录到redis
redis-cli
auth 520127
3、基本命令
keys * # 获取当前数据库中的所有key值
select 3 # 跳转到哪一个数据库,redis默认有16个数据库
二、String
########################################################
set views 0 # 设置值
get views # 获取值
#########################################################
APPEND views "hello" # 追加字符串
STRLEN views # 获取字符串长度
##########################################################
# i++/i--
incr views # 自增
decr views # 自减
###########################################################
INCRBY views 10 # 一次增加10
DECRBY views 10 # 一次减少10
############################################################
# 截取字符串 range
127.0.0.1:6379> set key1 "hello,gj"
OK
127.0.0.1:6379> get key1
"hello,gj"
127.0.0.1:6379> GETRANGE key1 0 3 # 截取1-3的字符 ,4个字符
"hell"
127.0.0.1:6379> GETRANGE key1 0 -1 # 截取所有字符串
"hello,gj"
###############################################################
# 替换
127.0.0.1:6379> set key2 abcdefghi
OK
127.0.0.1:6379> SETRANGE key2 2 ww
(integer) 9
127.0.0.1:6379> get key2
"abwwefghi"
###################################################################
# setex (set with expire) # 设置过期时间
# setnx (set if not exist) # 不存在在设置(在分布式锁中常用)
127.0.0.1:6379> setex key3 30 hello # 设置key3为hello,30秒过期
OK
127.0.0.1:6379> ttl key3 # 查看key3的剩余时间
(integer) 24
127.0.0.1:6379> setnx mykey redis # 不存在设置myredis
(integer) 1
127.0.0.1:6379> keys * # key3已过期,这里不显示
1) "mykey"
2) "key2"
3) "key1"
127.0.0.1:6379> ttl key3 # key3已过期,返回-2
(integer) -2
127.0.0.1:6379> setnx mykey mysql # myredis已存在,创建失败
(integer) 0
127.0.0.1:6379> get mykey
"redis"
127.0.0.1:6379>
###################################################################
# mset 批量设置值
# mget 批量获取值
127.0.0.1:6379> mset key1 gj key2 gjj key3 gjjj # 批量设置值
OK
127.0.0.1:6379> get key2
"gjj"
127.0.0.1:6379> keys * # 都已经设置
1) "key3"
2) "key2"
3) "key1"
127.0.0.1:6379> mget key1 key2 key3 # 批量获取值
1) "gj"
2) "gjj"
3) "gjjj"
127.0.0.1:6379> msetnx key1 jg key4 jjjjg # msetnx 是原子操作,如果存在,则创建失败
(integer) 0
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
3) "key1"
###################################################################
# 设置对象
127.0.0.1:6379> mset user:1:name gj user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "gj"
2) "2"
127.0.0.1:6379> set user:1 {name:gj,age:22}
OK
127.0.0.1:6379> get user:1
"{name:gj,age:22}"
###################################################################
# getset 先get后set
# 如果不存在。返回null,存在更新值。可以做一些更新操作
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mysql
"redis"
127.0.0.1:6379> get db
"mysql"
###################################################################
-
String 使用场景:
计数器
粉丝数
三、List
所有list命令都是以 l 开头
###################################################################
127.0.0.1:6379> lpush list one # lpush 将一个值或多个值插入头部
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 2
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 -1 # lrange 取出所有值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> rpush list gj # rpush 从尾部插入数据
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "gj"
###################################################################
# 移除命令 pop
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "gj"
127.0.0.1:6379> lpop list
"three"
127.0.0.1:6379> rpop list
"gj"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
###################################################################
# lindex 根据下标获取值
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 0
"two"
###################################################################
# llen 返回列表长度
127.0.0.1:6379> llen list
(integer) 2
###################################################################
# lrem 移除指定的值
127.0.0.1:6379> lpush list one
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "two"
3) "one"
127.0.0.1:6379> lrem list 1 one
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lpush list one
(integer) 2
127.0.0.1:6379> lpush list one
(integer) 3
127.0.0.1:6379> lpush list one
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "one"
3) "one"
4) "two"
127.0.0.1:6379> lrem list 2 one
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "one"
2) "two"
###################################################################
# trim 截取
127.0.0.1:6379> clear
127.0.0.1:6379> lpush list hello1
(integer) 1
127.0.0.1:6379> lpush list hello2
(integer) 2
127.0.0.1:6379> lpush list hello3
(integer) 3
127.0.0.1:6379> lpush list hello4
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "hello4"
2) "hello3"
3) "hello2"
4) "hello1"
127.0.0.1:6379> ltrim list 1 2 # 截取指定的长度,通过下标
OK
127.0.0.1:6379> lrange list 0 -1
1) "hello3"
2) "hello2"
###################################################################
# rpoplpush 移除列表的最后一个元素,并添加到一个新的列表中
127.0.0.1:6379> rpush list gj
(integer) 1
127.0.0.1:6379> rpush list gjj
(integer) 2
127.0.0.1:6379> rpush list gjjj
(integer) 3
127.0.0.1:6379> rpoplpush list mylist
"gjjj"
127.0.0.1:6379> lrange list 0 -1 #查看原来列表
1) "gj"
2) "gjj"
127.0.0.1:6379> lrange mylist 0 -1 # 查看新的列表
1) "gjjj"
###################################################################
# lset 指定下标存值,下标存在,覆盖值,相当于更新操作
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrang list 0 -1
127.0.0.1:6379> lrange list 0 -1
1) "value1"
127.0.0.1:6379> lset list 0 item # 下标存在。覆盖值
OK
127.0.0.1:6379> lrange list 0 -1
1) "item"
127.0.0.1:6379> lset list 1 item1 # 下标不存在,报错
(error) ERR index out of range
###################################################################
# 插入值 linsert
127.0.0.1:6379> clear
127.0.0.1:6379> lpush list gj
(integer) 1
127.0.0.1:6379> lpush list gjj
(integer) 2
127.0.0.1:6379> lpush list gjjj
(integer) 3
127.0.0.1:6379> linsert list before gj love # 向指定数据之前插入数据
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "gjjj"
2) "gjj"
3) "love"
4) "gj"
127.0.0.1:6379> linsert list after gjj zy # 向指定数据之后插入数据
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "gjjj"
2) "gjj"
3) "zy"
4) "love"
5) "gj"
###################################################################
四、Set(Set中的值不可以重复)
###################################################################
# 创建、赋值、读取值(不允许有重复值)
127.0.0.1:6379> clear
127.0.0.1:6379> sadd myset hello
(integer) 1
127.0.0.1:6379> sadd myset hello
(integer) 0
127.0.0.1:6379> sadd myset gj
(integer) 1
127.0.0.1:6379> sadd myset gjj
(integer) 1
127.0.0.1:6379> sadd myset gjjj
(integer) 1
127.0.0.1:6379> sadd myset love gjjj
(integer) 1
127.0.0.1:6379> smembers myset
1) "gjjj"
2) "gj"
3) "love"
4) "gjj"
5) "hello"
###################################################################
# SISMEMBER 查看值是否存在,存在返回1,不存在返回0
127.0.0.1:6379> SISMEMBER myset gj
(integer) 1
127.0.0.1:6379> SISMEMBER myset gjjjjjj
(integer) 0
###################################################################
# scard 获取set集合中数量
127.0.0.1:6379> scard myset
(integer) 5
###################################################################
# srem 移除
127.0.0.1:6379> srem myset gj
(integer) 1
127.0.0.1:6379> smembers myset
1) "love"
2) "gjj"
3) "hello"
4) "gjjj"
###################################################################
# set 无序不重复集合 可以抽随机
# srandmember 随机抽取一个元素
127.0.0.1:6379> smembers myset
1) "love"
2) "gjj"
3) "hello"
4) "gjjj"
127.0.0.1:6379> srandmember myset
"love"
127.0.0.1:6379> srandmember myset
"hello"
127.0.0.1:6379> srandmember myset
"love"
127.0.0.1:6379> srandmember myset
"gjjj"
###################################################################
# 删除指定的 值
# 删除随机的 值
# spop 随机移除元素
127.0.0.1:6379> smembers myset
1) "love"
2) "gjj"
3) "hello"
4) "gjjj"
127.0.0.1:6379> spop myset
"love"
127.0.0.1:6379> spop myset
"gjjj"
127.0.0.1:6379> smembers myset
1) "gjj"
2) "hello"
# 指定的值移动到另外一个set集合中
# smove
127.0.0.1:6379> sadd myset1 gj
(integer) 1
127.0.0.1:6379> sadd myset1 gjj
(integer) 1
127.0.0.1:6379> sadd myset1 gjjj
(integer) 1
127.0.0.1:6379> sadd myset1 gjjjj
(integer) 1
127.0.0.1:6379> smembers myset1
1) "gjjjj"
2) "gjj"
3) "gjjj"
4) "gj"
127.0.0.1:6379> sadd myset2 zy
(integer) 1
127.0.0.1:6379> sadd myset2 zyy
(integer) 1
127.0.0.1:6379> sadd myset2 zyyy
(integer) 1
127.0.0.1:6379> sadd myset2 zyyyy
(integer) 1
127.0.0.1:6379> smembers myset2
1) "zyyy"
2) "zyyyy"
3) "zyy"
4) "zy"
127.0.0.1:6379> smove myset1 myset2 gj
(integer) 1
127.0.0.1:6379> smembers myset1
1) "gjjjj"
2) "gjj"
3) "gjjj"
127.0.0.1:6379> smembers myset2
1) "zyyy"
2) "zyyyy"
3) "zyy"
4) "zy"
5) "gj"
###################################################################
# 共同关注 交集 差集 并集
127.0.0.1:6379> sadd key1 a
(integer) 1
127.0.0.1:6379> sadd key1 b
(integer) 1
127.0.0.1:6379> sadd key1 c
(integer) 1
127.0.0.1:6379> sadd key2 c
(integer) 1
127.0.0.1:6379> sadd key2 d
(integer) 1
127.0.0.1:6379> sadd key2 e
(integer) 1
127.0.0.1:6379> sdiff key1 key2 # 差集,key1和key2不同的元素
1) "b"
2) "a"
127.0.0.1:6379> sinter key1 key2 # 交集,key1和key2相同的元素 共同好友可以这么实现
1) "c"
127.0.0.1:6379> sunion key1 key2 # 并集,key1和key2所有的元素
1) "a"
2) "c"
3) "e"
4) "b"
5) "d"
###################################################################
五、Hash
###################################################################
# hset hget 赋值、取值
# hmset hmget 一次多次赋值、取值
# hgetall 获取所有数据
127.0.0.1:6379> hset myhash hash1 gj
(integer) 1
127.0.0.1:6379> hget myhash hash1
"gj"
127.0.0.1:6379> hmset myhash1 hash1 gj hash2 gjj hash3 gjjj
OK
127.0.0.1:6379> hmget myhash1 hash1 hash2 hash3
1) "gj"
2) "gjj"
3) "gjjj"
127.0.0.1:6379> hgetall myhash1
1) "hash1"
2) "gj"
3) "hash2"
4) "gjj"
5) "hash3"
6) "gjjj"
###################################################################
# hdel 删除指定的key字段,对应的value也就消失了
127.0.0.1:6379> hdel myhash1 hash1
(integer) 1
127.0.0.1:6379> hgetall myhash1
1) "hash2"
2) "gjj"
3) "hash3"
4) "gjjj"
###################################################################
# hlen 获取长度
127.0.0.1:6379> hlen myhash1
(integer) 2 # 只有2个键值对
###################################################################
# hexists 判断某个key是否存在
127.0.0.1:6379> hgetall myhash1
1) "hash2"
2) "gjj"
3) "hash3"
4) "gjjj"
127.0.0.1:6379> hexists myhash1 hash2
(integer) 1
###################################################################
# hkeys 只获得所有的key
# hvals 只获得所有的value
127.0.0.1:6379> hkeys myhash1
1) "hash2"
2) "hash3"
127.0.0.1:6379> hvals myhash1
1) "gjj"
2) "gjjj"
###################################################################
# 自增、自减
# hincrby myhash1 hash5 -1 相当于自减
127.0.0.1:6379> hset myhash1 hash5 5
(integer) 1
127.0.0.1:6379> hincrby myhash1 hash5 3
(integer) 8
127.0.0.1:6379> hget myhash1 hash5
"8"
###################################################################
# hsetnx 不存在则创建,存在创建失败
127.0.0.1:6379> hsetnx myhash1 hash4 hello
(integer) 1
127.0.0.1:6379> hsetnx myhash1 hash4 hello
(integer) 0
###################################################################
Hash使用场景:变更的数据(经常变动的信息,用户信息等。。。)
六、Zset (有序集合)
在set基础上加了一个值
###################################################################
# zadd zrange key 0 -1
127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset 2 two
(integer) 1
127.0.0.1:6379> zadd myzset 3 three
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"
###################################################################
# zrangebyscore 排序 升序
# zrevrangebyscore 降序
127.0.0.1:6379> zadd salary 2500 xiaohong 5000 gjj 500 gj
(integer) 3
127.0.0.1:6379> zrangebyscore salary -inf +inf
1) "gj"
2) "xiaohong"
3) "gjj"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores # 带上数据
1) "gj"
2) "500"
3) "xiaohong"
4) "2500"
5) "gjj"
6) "5000"
127.0.0.1:6379> zrangebyscore salary -inf 2500 withscores # 2500之内
1) "gj"
2) "500"
3) "xiaohong"
4) "2500"
127.0.0.1:6379> zrevrangebyscore salary +inf -inf withscores # 降序 zrevrange salary +inf -inf
1) "gjj"
2) "5000"
3) "xiaohong"
4) "2500"
5) "gj"
6) "500"
###################################################################
# zrem 移除
127.0.0.1:6379> zrange salary 0 -1
1) "gj"
2) "xiaohong"
3) "gjj"
127.0.0.1:6379> zrem salary xiaohong
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "gj"
2) "gjj"
###################################################################
# zcard 获取有序集合中的个数
127.0.0.1:6379> zcard salary
(integer) 2
###################################################################
# 区间
#升序、降序补充
127.0.0.1:6379> zadd zset1 2500 xiaohong 2300 gj 3000 gjj
(integer) 3
127.0.0.1:6379> zrange zset1 0 -1
1) "gj"
2) "xiaohong"
3) "gjj"
127.0.0.1:6379> zrevrange zset1 0 -1
1) "gjj"
2) "xiaohong"
3) "gj"
# zcount 区间
127.0.0.1:6379> zcount zset1 2300 3000
(integer) 3
###################################################################
七、地理位置
###################################################################
# geoadd 添加地理位置,两极不可添加
127.0.0.1:6379> geoadd China:city 116.40 39.90 beijing
(integer) 1
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
(integer) 1
127.0.0.1:6379> geoadd China:city 114.05 22.52 shenzhen
(integer) 1
127.0.0.1:6379> geoadd China:city 120.16 30.24 hangzhou
(integer) 1
127.0.0.1:6379> geoadd China:city 108.96 34.26 xian
(integer) 1
###################################################################
# geopos 获取存入的地理信息
127.0.0.1:6379> geopos China:city beijing shanghai
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
2) 1) "121.47000163793563843"
2) "31.22999903975783553"
###################################################################
# geodist 获取两地距离
127.0.0.1:6379> geodist China:city beijing shanghai
"1067378.7564"
# 可指定单位
127.0.0.1:6379> geodist China:city beijing shanghai km
"1067.3788"
127.0.0.1:6379> geodist China:city tianjin lvliang km
"587.6883"
###################################################################
# georadius 附近的人 获得所有附近人的定位,通过半径查询
127.0.0.1:6379> georadius China:city 110.00 30.00 1000 km
1) "chongqing"
2) "xian"
3) "lvliang"
4) "shenzhen"
5) "hangzhou"
# count 限制个数
127.0.0.1:6379> georadius China:city 110.00 30.00 1000 km withcoord withdist count 3
1) 1) "chongqing"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
2) 1) "xian"
2) "483.8340"
3) 1) "108.96000176668167114"
2) "34.25999964418929977"
3) 1) "lvliang"
2) "842.0294"
3) 1) "111.14999860525131226"
2) "37.50999883692443149"
###################################################################
八、事务
redis 事务本质:一组命令的集合,在事务的执行过程中,会按顺序执行。一致性、顺序性、排他性。
- 事务:CAID 一致性、隔离性、持久性、原子性
- redis 的单条命令保证原子性,但事务不保证原子性
- redis 的事务没有隔离级别
- redis 事务:
- 开启事务 (multi)
- 命令入队 (命令…)
- 执行事务 (exec)
###################################################################
# multi 开启事务
# 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> set k3 v3
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) "v2"
4) OK
# 执行完事务,这个事务就没了
###################################################################
- 放弃事务 discard
###################################################################
# discard 取消事务,事务中的命令没有被执行
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get k4
(nil)
###################################################################
- 事务中有错
- 代码有问题,命令有错。入队就会有提示。事务中命令都不会被执行!
- 如果事务中存在语法性错误,那么在执行时其余命令可以正常执行,出错命令不执行!
九、redis 监视测试
监控 watch
- 悲观锁:
- 认为什么时候都会出问题。无论做什么都会加锁。
- 乐观锁:
- 认为什么时候都不会出问题,所以不会上锁。更新的时候判断一下,在此期间,是否有人修改过数据,version!
- 获取version
- 更新时比较version
###################################################################
# 正常执行成功
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money # 监视money
OK
127.0.0.1:6379> multi # 事务正常结束,数据没有发生变动
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
事务执行失败,先解锁。# unwatch