127.0.0.1:6379> keys * # 查看当前数据库所有key (empty list or set) 127.0.0.1:6379> set name qinjiang # set key OK 127.0.0.1:6379> set age 20 OK 127.0.0.1:6379> keys * 1) "age" 2) "name" 127.0.0.1:6379> move age 1 # 将键值对移动到指定数据库 (integer) 1 127.0.0.1:6379> EXISTS age # 判断键是否存在 (integer) 0 # 不存在 127.0.0.1:6379> EXISTS name (integer) 1 # 存在 127.0.0.1:6379> SELECT 1 OK 127.0.0.1:6379[1]> keys * 1) "age" 127.0.0.1:6379[1]> del age # 删除键值对 (integer) 1 # 删除个数
127.0.0.1:6379> set age 20 OK 127.0.0.1:6379> EXPIRE age 15 # 设置键值对的过期时间
(integer) 1 # 设置成功 开始计数 127.0.0.1:6379> ttl age # 查看key的过期剩余时间 (integer) 13 127.0.0.1:6379> ttl age (integer) 11 127.0.0.1:6379> ttl age (integer) 9 127.0.0.1:6379> ttl age (integer) -2 # -2 表示key过期,-1表示key未设置过期时间
127.0.0.1:6379> get age # 过期的key 会被自动delete (nil) 127.0.0.1:6379> keys * 1) "name"
127.0.0.1:6379> GETSET db redis #如果不存在值,返回null (nil) 127.0.0.1:6379> GET db "redis" 127.0.0.1:6379> GETSET db mongodb #如果存在值,获取原来值,并设置新值 "redis" 127.0.0.1:6379> GET db "mongodb"
List
基本的数据类型,列表。
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> LRANGE list 0 -1 #获取list的值 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 hello (integer) 4 127.0.0.1:6379> LRANGE list 0 -1 #右插 1) "three" 2) "two" 3) "one" 4) "hello" 127.0.0.1:6379> LPOP list #左移除一个元素 "three" 127.0.0.1:6379> RPOP list #右移除一个元素 "hello" 127.0.0.1:6379> 127.0.0.1:6379> LRANGE list 0 -1 1) "two" 2) "one" 127.0.0.1:6379> LINDEX list 1 #通过下标获取值 "one" 127.0.0.1:6379> LINDEX list 0 "two"
127.0.0.1:6379> LPUSH list v1 (integer) 1 127.0.0.1:6379> LPUSH list v2 (integer) 2 127.0.0.1:6379> LPUSH list v3 (integer) 3 127.0.0.1:6379> LRANGE list 0 -1 1) "v3" 2) "v2" 3) "v1" 127.0.0.1:6379> LLEN list |#返回列表的长度 (integer) 3 127.0.0.1:6379> LREM list 1 v1 #移除list列表中1个v1 (integer) 1 127.0.0.1:6379> LRANGE list 0 -1 1) "v3" 2) "v2"
127.0.0.1:6379> RPUSH list v1 (integer) 1 127.0.0.1:6379> RPUSH list v2 (integer) 2 127.0.0.1:6379> RPUSH list v3 (integer) 3 127.0.0.1:6379> LTRIM list 1 2 OK 127.0.0.1:6379> LRANGE list 0 -1 1) "v2" 2) "v3"
127.0.0.1:6379> EXISTS list #判断list是否存在 (integer) 0 127.0.0.1:6379> RPUSH list v1 (integer) 1 127.0.0.1:6379> LSET list 0 vv #设置0索引位置值为vv OK 127.0.0.1:6379> LRANGE list 0 -1 1) "vv" 127.0.0.1:6379> LSET list 1 v2 #设置不存在的报错 (error) ERR index out of range
127.0.0.1:6379> LRANGE list 0 -1 1) "v1" 2) "v2" 3) "v3" 4) "v4" 127.0.0.1:6379> LINSERT list before v2 oo #往指定list表位置之前插入 (integer) 5 127.0.0.1:6379> LRANGE list 0 -1 1) "v1" 2) "oo" 3) "v2" 4) "v3" 5) "v4" 127.0.0.1:6379> LINSERT list after v4 aa (integer) 6 127.0.0.1:6379> LRANGE list 0 -1 1) "v1" 2) "oo" 3) "v2" 4) "v3" 5) "v4" 6) "aa"
小结
实际上是一个链表,before Node after
列表中的元素是有序的,可以通过索引下标来获取某个元素或者某个范围内的元素列表
列表中的元素是可以重复的
Set
127.0.0.1:6379> SADD list v1 #set集合中添加 (integer) 1 127.0.0.1:6379> SADD list v2 (integer) 1 127.0.0.1:6379> SADD list v3 (integer) 1 127.0.0.1:6379> SADD list v4 (integer) 1 127.0.0.1:6379> SMEMBERS list #查看指定set的所有值 1) "v4" 2) "v3" 3) "v2" 4) "v1" 127.0.0.1:6379> SISMEMBER list v2 #判断某一个值是否存在,1存在,0不存在 (integer) 1 127.0.0.1:6379> SISMEMBER list vv (integer) 0
127.0.0.1:6379> SCARD list #查看集合中元素的个数 (integer) 4 127.0.0.1:6379> SREM list v2 #移除集合中的元素 (integer) 1 127.0.0.1:6379> SMEMBERS list 1) "v4" 2) "v3" 3) "v1"
127.0.0.1:6379> SRANDMEMBER list #随机抽选出一个元素 "v4" 127.0.0.1:6379> 127.0.0.1:6379> SRANDMEMBER list "v1"
127.0.0.1:6379> SPOP list #随机移除元素 "v3" 127.0.0.1:6379> SMEMBERS list 1) "v4" 2) "v1"
127.0.0.1:6379> SADD list hello1 (integer) 1 127.0.0.1:6379> SADD list hello2 (integer) 1 127.0.0.1:6379> SADD list hello3 (integer) 1 127.0.0.1:6379> SADD list2 2 (integer) 1 127.0.0.1:6379> SMOVE list list2 hello2 #指定一个值,移到另一个集合 (integer) 1 127.0.0.1:6379> SMEMBERS list 1) "hello3" 2) "hello1" 127.0.0.1:6379> SMEMBERS list2 1) "hello2" 2) "2"
----------PFADD--PFCOUNT--------------------- 127.0.0.1:6379> PFADD myelemx a b c d e f g h i j k # 添加元素 (integer) 1 127.0.0.1:6379> type myelemx # hyperloglog底层使用String string 127.0.0.1:6379> PFCOUNT myelemx # 估算myelemx的基数 (integer) 11 127.0.0.1:6379> PFADD myelemy i j k z m c b v p q s (integer) 1 127.0.0.1:6379> PFCOUNT myelemy (integer) 11
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 k1 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> EXEC #执行事务 1) OK 2) OK 3) "v1" 4) OK
取消事务
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 k1 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> set k4 v4 QUEUED 127.0.0.1:6379> DISCARD #放弃事务 OK 127.0.0.1:6379> get k4 (nil)
编译型异常(代码有问题!命令有错! ),事务中所有的命令 都不会被执行!
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> setget k1 #错误的命令 (error) ERR unknown command `setget`, with args beginning with: `k1`, 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> EXEC #执行事务报错 (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get k3 (nil)
==如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常!==
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> INCR k1 #执行时候失败 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> get k3 QUEUED 127.0.0.1:6379> EXEC 1) OK 2) (error) ERR value is not an integer or out of range #错误命令,但是其他依然执行成功 3) OK 4) OK 5) "v3"
监控
悲观锁
什么情况下都去加锁
乐观锁
一般不是上锁,只有更新数据的时候去判断一下,此期间数据是否改变
获取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
测试多线程修改值,使用watch可以当做redis的乐观锁操作!
127.0.0.1:6379> set m1 100 OK 127.0.0.1:6379> KEYS * 1) "m1" 127.0.0.1:6379> get m1 "100" 127.0.0.1:6379> WATCH m1 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> DECRBY m1 10 QUEUED 127.0.0.1:6379> INCRBY m1 20 QUEUED 127.0.0.1:6379> EXEC #执行前开启另外一个线程修改m1的值为200 (nil) 127.0.0.1:6379> GET m1 "200"
127.0.0.1:6379> UNWATCH #事务执行失败,先解锁 OK 127.0.0.1:6379> WATCH m1 #然后监视,最新的值 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> DECRBY m1 10 QUEUED 127.0.0.1:6379> INCRBY m1 20 QUEUED 127.0.0.1:6379> EXEC #对比监视的值,如果没变,一致即可执行成功,反之失败null 1) (integer) 190 2) (integer) 210