Redis安装和基本数据类型及其命令的学习

安装

https://pan.baidu.com/s/1fI4KkwkN60NNk4dEe4URBA?pwd=1234

Linux 安装命令

tar -zxvf redis-7.0.4.tar.gz

cd redis-7.0.4

make

make

make install

修改redis.config配置文件,让其后台启动
在这里插入图片描述

启动

启动Redis服务

[root@localhost bin]# redis-server conf/redis.conf 
[root@localhost bin]# redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set name coffeemao
OK
127.0.0.1:6379> get name
"coffeemao"

查看Redis服务是否开启

[root@localhost ~]# ps -ef|grep redis
root       2636      1  0 21:19 ?        00:00:00 redis-server 127.0.0.1:6379
root       2649   2366  0 21:19 pts/0    00:00:00 redis-cli -p 6379
root       2724   2673  0 21:22 pts/1    00:00:00 grep --color=auto redis
[root@localhost ~]# 

关闭Redis服务

127.0.0.1:6379> shutdown
not connected> exit
[root@localhost bin]# ps -ef|grep redis
root       2822   2673  0 21:28 pts/1    00:00:02 redis-benchmark -h localhost -p
root       3356   2366  0 22:15 pts/0    00:00:00 grep --color=auto redis
[root@localhost bin]# kill -9 2822
[root@localhost bin]# ps -ef | grep redis
root       3385   2366  0 22:17 pts/0    00:00:00 grep --color=auto redis

redis-benchmark压力测试工具,并发10000

[root@localhost bin]# redis-benchmark -h localhost -p 6379 -c 100 -n 10000

基本知识

Redis 默认16个数据库,默认使用第一个数据库

# 清除当前数据库
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
# 清除全部数据库
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> 

Redis是单线程的,基于内存操作,CPU不影响Redis,影响Redis的因素是网络和计算机内存,C语言编写的。
Redis将所有的数据放到内存里面,因为多线程的切换会造成CPU上下文的切换,对于内存系统来讲,没有上下文切换速度就是最高的,最佳方案多次读写都在一个CPU上进行

Redis-key

存储数据SET KEY VALUE
判断数据是否存在EXISTS name
设置字段过期EXPIRE name 10
查看字段过期倒计时ttl name,结果时间到 -2时,过期之后数据库中不存在
移动到其他数据库move name 1
查看当前key的数据类型type key

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set name coffeemao
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> EXPIRE name 10
(integer) 1
127.0.0.1:6379> ttl name
(integer) 7
127.0.0.1:6379> ttl name
(integer) 6
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> keys *
1) "name"

127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name"
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set name coffee
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> type name
string
127.0.0.1:6379> type age
string
127.0.0.1:6379> 

String

尾部追加 APPEND name mao

字符串长度STRLEN name

自增 1 INCR views
自减 1 DECR views

自增步长 step INCRBY views 5
自减步长 step DECRBY views 5

截取字符串长度闭区间 GETRANGE name 0 2
字符串的全部输出GETRANGE name 0 -1相当于 get name

字符串的替换SETRANGE name1 0 -

存在字符串 setex time 10 "hour"
不存在字符串就设置 setnx name "hello"

设置多个键值对 mset k1 v1 k2 v2 k3 v3 k4 v4
与的原子性操作msetnx k1 v1 k5 v5

对象设置mset user:1:name coffeemao user:1:age 18
获取mget user:1:name user:1:age

先get在setgetset db redis

127.0.0.1:6379> set name coffee
OK
127.0.0.1:6379> get name
"coffee"
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> APPEND name mao
(integer) 9
127.0.0.1:6379> get name
"coffeemao"
127.0.0.1:6379> APPEND name ",hello,world"
(integer) 21
127.0.0.1:6379> STRLEN name
(integer) 21
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"coffeemao,hello,world"
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> keys *
1) "views"
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> INCR views 
(integer) 1
127.0.0.1:6379> INCR views 
(integer) 2
127.0.0.1:6379> INCR views 
(integer) 3
127.0.0.1:6379> get views
"3"
127.0.0.1:6379> DECR views
(integer) 2
127.0.0.1:6379> DECR views
(integer) 1
127.0.0.1:6379> INCRBY views 10
(integer) 11
127.0.0.1:6379> INCRBY views 10
(integer) 21
127.0.0.1:6379> DECRBY views 5
(integer) 16
127.0.0.1:6379> DECRBY views 10
(integer) 6
127.0.0.1:6379> DECRBY views 5
(integer) 1
127.0.0.1:6379> set name hello coffee mao,hello world
(error) ERR syntax error
127.0.0.1:6379> set name "hello coffee mao hello world"
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"hello coffee mao hello world"
127.0.0.1:6379> GETRANGE name 0 2
"hel"
127.0.0.1:6379> GETRANGE name 0 -1
"hello coffee mao hello world"
127.0.0.1:6379> set name1 "0123456"
OK
127.0.0.1:6379> SETRANGE name1 0 2
(integer) 7
127.0.0.1:6379> get name
"hello coffee mao hello world"
127.0.0.1:6379> get name1
"2123456"
127.0.0.1:6379> SETRANGE name1 0 ---
(integer) 7
127.0.0.1:6379> get name1
"---3456"

127.0.0.1:6379> setex time 10 "hour"
OK
127.0.0.1:6379> ttl time
(integer) 3
127.0.0.1:6379> ttl time
(integer) 0
127.0.0.1:6379> ttl time
(integer) -2
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> setnx name "hello"
(integer) 1
127.0.0.1:6379> setnx name "heo"
(integer) 0
127.0.0.1:6379> get name
"hello"

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 k4 v4
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k4"
3) "k3"
4) "k2"

# 原子性操作
127.0.0.1:6379> msetnx k1 v1 k5 v5
(integer) 0
127.0.0.1:6379> msetnx k1 v1 k4 v4
(integer) 0
127.0.0.1:6379> msetnx k1 v1
(integer) 0
127.0.0.1:6379> msetnx k5 v5
(integer) 1
127.0.0.1:6379> 

127.0.0.1:6379> mset user:1:name coffeemao user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "coffeemao"
2) "2"

# 先 get 再 set
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db oracle
"redis"
127.0.0.1:6379> get db
"oracle"
127.0.0.1:6379> 

List

集合的增加元素 LPUSH list one
集合左部弹出元素 LPOP list 1

集合长度 llen list

获取集合制定索引的元素 LINDEX list 0

移除集合指定位置的元素 LREM list 1 three

截断修改集合 LTRIM list 1 2

集合右部弹出左加入到新的集合中 rpoplpush list list1

修改指定索引的元素值 lset list 0 *

在集合指定元素之前或之后插入目标元素 linsert list before 1 mao

127.0.0.1:6379> LPUSH list one
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> keys *
1) "list"
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1
1) "three"
2) "two"
127.0.0.1:6379> RPUSH list four
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
127.0.0.1:6379> LPOP list 1
1) "three"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
3) "four"
127.0.0.1:6379> RPOP list 2
1) "four"
2) "one"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
127.0.0.1:6379> LINDEX list 0
"two"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> LPUSH list ont
(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> LPUSH list four
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "four"
2) "three"
3) "two"
4) "ont"
127.0.0.1:6379> LLEN list
(integer) 4
127.0.0.1:6379> LREM list 1 three
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "four"
2) "two"
3) "ont"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> LPUSH list one
(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> LPUSH list four
(integer) 4
127.0.0.1:6379> LTRIM list 1 2
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
127.0.0.1:6379> keys *
1) "list"
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
127.0.0.1:6379> rpoplpush list list1
"two"
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
127.0.0.1:6379> LRANGE list1 0 -1
1) "two"
127.0.0.1:6379> LPUSH list one
(integer) 2


127.0.0.1:6379> lrange list  0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lset list 0 *
OK
127.0.0.1:6379> lrange list  0 -1
1) "*"
2) "two"
3) "one"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> clear
127.0.0.1:6379> LPUSh list 1
(integer) 1
127.0.0.1:6379> LPUSH list 2
(integer) 2
127.0.0.1:6379> LPUSH list 3
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> lset list 3 mao
(error) ERR index out of range
127.0.0.1:6379> lset list 2 mao
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "3"
2) "2"
3) "mao"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> linsert list before 1 mao
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "mao"
2) "1"
127.0.0.1:6379> linsert list after mao coffee
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "mao"
2) "coffee"
3) "1"

Set

增加元素 sadd set hello
查询集合中元素的个数 scard set
查询集合所有的元素 smembers set
判断集合中是否存指定元素 sismember set hello
集合移除制定元素 srem set hello
随机抽取集合指定个数的元素 srandmember set 2
随机删除指定元素 spop set
转移集合中指定元素 smove set set1 hello
集合的差集sdiff set set1
集合的交集 sinter set set1
集合的并集 sunion set set1

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd set hello
(integer) 1
127.0.0.1:6379> sadd set hello
(integer) 0
127.0.0.1:6379> sadd set world
(integer) 1
127.0.0.1:6379> scard set
(integer) 2
127.0.0.1:6379> smembers set
1) "hello"
2) "world"
127.0.0.1:6379> sismember set hello
(integer) 1
127.0.0.1:6379> srem set hello
(integer) 1
127.0.0.1:6379> scard set
(integer) 1
127.0.0.1:6379> smembers set
1) "world"
127.0.0.1:6379> smembers set
1) "hello1"
2) "hello"
3) "hello2"
4) "world"
5) "hello3"
127.0.0.1:6379> srandmember set 2
1) "hello1"
2) "world"
127.0.0.1:6379> spop set
"hello3"
127.0.0.1:6379> smembers set
1) "hello1"
2) "hello"
3) "hello2"
4) "world"
127.0.0.1:6379> sadd set1 1
(integer) 1
127.0.0.1:6379> sadd set1 2
(integer) 1
127.0.0.1:6379> smove set set1 hello
(integer) 1
127.0.0.1:6379> smembers set1
1) "hello"
2) "1"
3) "2"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
1) "set1"
2) "set"
127.0.0.1:6379> smembers set
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> smembers set1
1) "c"
127.0.0.1:6379> sadd set1 d
(integer) 1
127.0.0.1:6379> sadd set1 e
(integer) 1
127.0.0.1:6379> sdiff set set1
1) "b"
2) "a"
127.0.0.1:6379> sinter set set1
1) "c"
127.0.0.1:6379> sunion set set1
1) "b"
2) "c"
3) "a"
4) "d"
5) "e"
127.0.0.1:6379> 

Map

key value = key map
增加元素 hset hash field1 coffeemao
根据字段获取元素值 hget hash field1
新增多个字段 hmset hash field1 hello field2 world
查询多个字段 hmget hash field1 field2
查询所有的键值对信息 hgetall hash
删除指定字段 hdel hash field2
长度 hlen hash
判断字段是否存在 hexists hash field1
查询所有的键 hkeys hash
查询所有的值 hvals hash
设置整数字段增加 HINCRBY hash field5 2

map 存储对象 hset user:1 name coffeemao
获取对象 hget user:1 name

127.0.0.1:6379> hset hash field1 coffeemao
(integer) 1
127.0.0.1:6379> hget hash field1
"coffeemao"
127.0.0.1:6379> hmset hash field1 hello field2 world
OK
127.0.0.1:6379> hmget hash field1 field2
1) "hello"
2) "world"
127.0.0.1:6379> hgetall hash
1) "field1"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> hdel hash field2
(integer) 1
127.0.0.1:6379> hgetall hash
1) "field1"
2) "hello"
127.0.0.1:6379> hlen hash
(integer) 1
127.0.0.1:6379> hmset hash field2 world field3 coffee field4 mao
OK
127.0.0.1:6379> hgetall hash
1) "field1"
2) "hello"
3) "field2"
4) "world"
5) "field3"
6) "coffee"
7) "field4"
8) "mao"
127.0.0.1:6379> hlen hash
(integer) 4
127.0.0.1:6379> hexists hash field1
(integer) 1
127.0.0.1:6379> hkeys hash
1) "field1"
2) "field2"
3) "field3"
4) "field4"
127.0.0.1:6379> hvals hash
1) "hello"
2) "world"
3) "coffee"
4) "mao"
127.0.0.1:6379> hset hash field5 5
(integer) 1
127.0.0.1:6379> HINCRBY hash field5 2
(integer) 7
127.0.0.1:6379> HINCRBY hash field5 -3
(integer) 4
127.0.0.1:6379> hsetnx hash field4 4
(integer) 0
127.0.0.1:6379> hset user:1 name coffeemao
(integer) 1
127.0.0.1:6379> hget user:1 name
"coffeemao"

ZSet
有序的 Set集合

增加元素zadd zset 1 one
查询全部所有元素 zrange zset 0 -1

由小到大排序 zrangebyscore salary -inf +inf
带分值 zrangebyscore salary -inf +inf withscores
由大到小排序 zrevrange salary 0 -1

移除元素 zrem salary xiaoming

查询集合长度 zcard salary
区间元素个数 zcount salary 250 700

127.0.0.1:6379> zadd zset 1 one
(integer) 1
127.0.0.1:6379> zadd zset 2 two
(integer) 1
127.0.0.1:6379> zadd zset 3 three
(integer) 1
127.0.0.1:6379> zadd zset 4 four 5 five
(integer) 2
127.0.0.1:6379> zrange zset 0 -1
1) "one"
2) "two"
3) "three"
4) "four"
5) "five"
127.0.0.1:6379> zadd salary 3000 xiaoming
(integer) 1
127.0.0.1:6379> keys *
1) "zset"
2) "salary"
127.0.0.1:6379> zadd salary 2500 zhangsan
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf
1) "zhangsan"
2) "xiaoming"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores
1) "zhangsan"
2) "2500"
3) "xiaoming"
4) "3000"
127.0.0.1:6379> zrange salary 0 -1
1) "zhangsan"
2) "xiaoming"
127.0.0.1:6379> zrem salary xiaoming
(integer) 1
127.0.0.1:6379> zcard salary
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "zhangsan"
127.0.0.1:6379> zadd salary 500 lisi
(integer) 1
127.0.0.1:6379> zrange salary  0 -1
1) "lisi"
2) "zhangsan"
127.0.0.1:6379> zrevrange salary 0 -1
1) "zhangsan"
2) "lisi"
127.0.0.1:6379> zcount salary 250 700
(integer) 1

Geospatical

http://www.redis.cn/commands/geoadd.html
先经度再维度
超出范围报错(error) ERR invalid longitude,latitude pair 34.230000,108.000000

增加城市地理信息 geoadd china:city 116.40 39.90 beijing
查询内部信息 geopos china:city beijing xian

两个地理位置之间的距离 geodist china:city beijing xian [km]
附件的人 georadius china:city 108.94 34.23 100 km
有限的附加的人 georadius china:city 110 30 10000 km withcoord count 2

指定元素之间的内容, 城市之间的定位 georadiusbymember china:city beijing 10000 km
二维经纬度转化为一位哈希字符串 geohash china:city beijing xian
地理位图是基于zset实现的,可以通过 zrem进行删除元素信息

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.83 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 108.94 34.23 xian
(integer) 1
127.0.0.1:6379> geopos china:city beijing xian
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
2) 1) "108.93999785184860229"
   2) "34.23000121926852302"
127.0.0.1:6379> geopos china:city xian
1) 1) "108.93999785184860229"
   2) "34.23000121926852302"
127.0.0.1:6379> geodist china:city beijing xian
"913730.3072"
127.0.0.1:6379> geodist china:city beijing shanghai km
"1006.7732"
127.0.0.1:6379> georadius china:city 108.94 34.23 100 km
1) "xian"
127.0.0.1:6379> georadius china:city 110 30 500 km withcoord
1) 1) "xian"
   2) 1) "108.93999785184860229"
      2) "34.23000121926852302"
      2) "34.23000121926852302"
127.0.0.1:6379> georadius china:city 110 30 10000 km withcoord count 2
1) 1) "xian"
   2) 1) "108.93999785184860229"
      2) "34.23000121926852302"
2) 1) "shanghai"
   2) 1) "121.47000163793563843"
      2) "31.83000048954843209"
127.0.0.1:6379> georadiusbymember china:city beijing 10000 km
1) "xian"
2) "shanghai"
3) "beijing"
127.0.0.1:6379> 
127.0.0.1:6379> geohash china:city beijing xian
1) "wx4fbxxfke0"
2) "wqj6wzrsjy0"
127.0.0.1:6379> zrange china:city 0 -1
1) "xian"
2) "shanghai"
3) "beijing"
127.0.0.1:6379> zrem china:city beijing
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "xian"
2) "shanghai"
127.0.0.1:6379> 

Hyperloglog

基数:不重复的元素的个数
占用内存十分的小,2^64 只需要 12KB
新建pfadd key a b c d e f g h i j
查看长度 pfcount key
合并 pfmerge key2 key key1
使用时有要容错的准备

127.0.0.1:6379> pfadd key a b c d e f g h i j
(integer) 1
127.0.0.1:6379> keys *
1) "key"
127.0.0.1:6379> pfcount key
(integer) 10
127.0.0.1:6379> pfadd key i j k
(integer) 1
127.0.0.1:6379> pfcount key
(integer) 11
127.0.0.1:6379> pfadd key1 i j k l m n o
(integer) 1
127.0.0.1:6379> pfcount key1
(integer) 7
127.0.0.1:6379> pfmerge key2 key key1
OK
127.0.0.1:6379> pfcount key2
(integer) 15

Bitmaps

位存储,只有0 和 1 两个状态
设置周一到周日打卡。周内打卡,双休不打卡
设置信息 setbit sign 0 1
获取信息 getbit sign 5
1 状态的个数 bitcount sign

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 1
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0
127.0.0.1:6379> getbit sign 0
(integer) 1
127.0.0.1:6379> getbit sign 5
(integer) 0
127.0.0.1:6379> bitcount sign
(integer) 5

事务

Redis 的单个命令原子性的,但是事务不保证原子性
Redis事务的本质:一组命令的集合,一个事务中的所有命令都会被序列化,在事务执的过程中,会按照顺序执行。一次性,顺序性,排他性
Redis事务没有隔离机制,只有发起命令的时候才会执行
开启事务
命令入队
执行事务
multi开启事务

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> get k1
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
3) "v1"
4) OK
127.0.0.1:6379> 

discard取消事务

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> discard
OK
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> 

代码错误,编译时候就会报错,执行事务会报错。所有命令都不会执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> discard
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> getset k2
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> 

运行时报错

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set k1 hello
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incr k1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> exec
1) (error) ERR value is not an integer or out of range
2) OK
127.0.0.1:6379> get k2
"v2"

监控

悲观锁:什么时候都会出问题,无论什么时候都会出现问题

乐观锁:不上锁,更新数据时候判断一下,在此期间是否有人修改这个数据。使用监控,监控money,开启事务,事务的命令入队,不执行,有线程插入进来,对监控的对象进行了修改,之后执行事务,发现事务执行失败。关闭监控,获取最新的值,重新监控money,开启事务,命令入队,没有线程插入(监控对象没有变化),执行成功。

监视 money 成功

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> clear
127.0.0.1:6379> flushall
OK
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
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 20
QUEUED
127.0.0.1:6379(TX)> incrby out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20
127.0.0.1:6379> 

执行失败
线程1

127.0.0.1:6379> keys *
(empty array)
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
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 20
QUEUED
127.0.0.1:6379(TX)> incrby out 20
QUEUED
127.0.0.1:6379(TX)>

线程 2

127.0.0.1:6379> get money
"100"
127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> get money
"1000"

线程 1 执行 ,失败

127.0.0.1:6379(TX)> exec
(nil)
127.0.0.1:6379> 
线程 2 已经对 money 进行了修改
127.0.0.1:6379> get money
"1000"
127.0.0.1:6379> unwatch
OK

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值