select 0(0-15) //切换第0个数据库 dbsize //查看当前数据库大小 flushdb //清除当前数据库 flushall //清除所有数据库 type name //判断key 类型 keys * //查看所有的key set name miaomiao //set key get name //get key del name //删除key name exists //判断当前key是否存在 move name 1 //移除key 在一号数据库 expire name 10 //设置key 10秒后过期 ttl name //查看当前key剩余时间 type name //查看当前key类型
string
127.0.0.1:6379> set key1 v1 OK 127.0.0.1:6379> keys * 1) "age" 2) "name" 3) "key1" 127.0.0.1:6379> exists key1 //查看key1是否存在 (integer) 1 127.0.0.1:6379> append key1 'hello' //为key1追加内容 (integer) 7 127.0.0.1:6379> exists key1 (integer) 1 127.0.0.1:6379> get key1 "v1hello" 127.0.0.1:6379> append key1 ',miaostudy' (integer) 17 127.0.0.1:6379> get key1 "v1hello,miaostudy" 127.0.0.1:6379> strlen key1 //查看key1字符长度 (integer) 17 127.0.0.1:6379> ################################### 127.0.0.1:6379> keys * 1) "age" 2) "name" 3) "key1" 127.0.0.1:6379> append key2 'aaabbb' //如果追加key不存在,就相当于set key (integer) 6 127.0.0.1:6379> keys * 1) "age" 2) "name" 3) "key1" 4) "key2" 127.0.0.1:6379> ############################################# 127.0.0.1:6379> set views 0 OK 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> decr views //减一 (integer) 1 127.0.0.1:6379> decr views (integer) 0 127.0.0.1:6379> incrby views 9 //设置一次性加9 (integer) 9 127.0.0.1:6379> incrby views 9 (integer) 18 127.0.0.1:6379> decrby views 5 //设置一次性减5 (integer) 13 127.0.0.1:6379> decrby views 5 (integer) 8 127.0.0.1:6379> ############################################ 字符串范围 range 127.0.0.1:6379> set info hfaksdhsdkjh OK 127.0.0.1:6379> get ingo (nil) 127.0.0.1:6379> get info "hfaksdhsdkjh" 127.0.0.1:6379> getrange info 0 3 //获取范围 "hfak" 127.0.0.1:6379> getrange info 0 -1 //-1 查看长度 "hfaksdhsdkjh" 127.0.0.1:6379> ############################################ setrange 替换 127.0.0.1:6379[2]> set key1 adcdeeee OK 127.0.0.1:6379[2]> get key1 "adcdeeee" 127.0.0.1:6379[2]> setrange key1 1 xx //d 替换 xx (integer) 8 127.0.0.1:6379[2]> get key1 "axxdeeee" 127.0.0.1:6379[2]> ####################################### setex(set with expire)设置过期时间 setnx(set if not exist)不存在设置 127.0.0.1:6379[2]> setex key3 30 'mymy'//设置key过期时间 OK 127.0.0.1:6379[2]> ttl key3 //查看剩余时间 (integer) 26 127.0.0.1:6379[2]> ttl key3 (integer) 14 127.0.0.1:6379[2]> get key3 (nil) 127.0.0.1:6379[2]> setnx mykey 'wodekey' //如果不存在设置key (integer) 1 127.0.0.1:6379[2]> get mykey "wodekey" 127.0.0.1:6379[2]> setnx mykey 'nidekey' (integer) 0 127.0.0.1:6379[2]> get mykey "wodekey" 127.0.0.1:6379[2]> ########################################## mset 一次设置多个值 mget 一次获取多个值 127.0.0.1:6379[2]> mset k1 v1 k2 v2//设置多个值 OK 127.0.0.1:6379[2]> keys * 1) "k2" 2) "k1" 127.0.0.1:6379[2]> mget k1 k2 //获取多个值 1) "v1" 2) "v2" 127.0.0.1:6379[2]> msetnx k1 v1 k3 v3 //msetnx是一个原子性操作,要么一起成功,要么一起失败 (integer) 0 127.0.0.1:6379[2]> keys * 1) "k2" 2) "k1" 127.0.0.1:6379[2]> ################################################ set user:1 {name:mm,age:22} 设置一个user:1 对象,值为json字符保存的对象 127.0.0.1:6379[2]> mset user:1:name lisi user:1:age 22 OK 127.0.0.1:6379[2]> mget user:1:name user:1:age 1) "lisi" 2) "22" 127.0.0.1:6379[2]> ################################################ getset 先get然后set 127.0.0.1:6379[2]> getset db redis //如果存在值 返回并设置新的值 (nil) 127.0.0.1:6379[2]> get db "redis" 127.0.0.1:6379[2]> getset db mogodb "redis" 127.0.0.1:6379[2]> get db "mogodb" 127.0.0.1:6379[2]>
list
所有的list命令都是用l 开头的
127.0.0.1:6379[2]> lpush list one //push元素进去头部 (integer) 1 127.0.0.1:6379[2]> lpush list two (integer) 2 127.0.0.1:6379[2]> lpush list three (integer) 3 127.0.0.1:6379[2]> lrange list 0 -1 //获取所有元素 1) "three" 2) "two" 3) "one" 127.0.0.1:6379[2]> lrange list 0 1 //获取范围元素 1) "three" 2) "two" 127.0.0.1:6379[2]> 127.0.0.1:6379[2]> lpush list left //添加元素位置在左边 (integer) 4 127.0.0.1:6379[2]> lrange list 0 -1 //获取list值 1) "left" 2) "three" 3) "two" 4) "one" 127.0.0.1:6379[2]> rpush list right //rpush 添加元素在右边 (integer) 5 127.0.0.1:6379[2]> lrange list 0 -1 //获取区间值 1) "left" 2) "three" 3) "two" 4) "one" 5) "right" 127.0.0.1:6379[2]> ############################################# lpop 弹出左边值 rpop 弹出右边值 127.0.0.1:6379[2]> lrange list 0 -1 1) "left" 2) "three" 3) "two" 4) "one" 5) "right" 127.0.0.1:6379[2]> lpop list //弹出左边值 "left" 127.0.0.1:6379[2]> rpop list //弹出右边值 "right" 127.0.0.1:6379[2]> lrange list 0 -1 1) "three" 2) "two" 3) "one" 127.0.0.1:6379[2]> ########################################### lindex 通过下标获取值 127.0.0.1:6379[2]> lrange list 0 -1 1) "three" 2) "two" 3) "one" 127.0.0.1:6379[2]> lindex list 1 //获取下标为1的值 "two" 127.0.0.1:6379[2]> lindex list 0 "three" 127.0.0.1:6379[2]> ############################################### llen 获取列表长度 127.0.0.1:6379[2]> lrange list 0 -1 1) "three" 2) "two" 3) "one" 127.0.0.1:6379[2]> llen list (integer) 3 127.0.0.1:6379[2]> ############################################# lrem 移除指定的值 127.0.0.1:6379[2]> lrange list 0 -1 1) "three" 2) "three" 3) "two" 4) "one" 127.0.0.1:6379[2]> lrem list 1 two //移除一个值为two (integer) 1 127.0.0.1:6379[2]> lrange list 0 -1 1) "three" 2) "three" 3) "one" 127.0.0.1:6379[2]> lrem list 2 three //移除两个值为three (integer) 2 127.0.0.1:6379[2]> lrange list 0 -1 1) "one" 127.0.0.1:6379[2]> ######################################### ltrim 截断list 127.0.0.1:6379[2]> rpush mylist hh1 (integer) 1 127.0.0.1:6379[2]> rpush mylist hh2 (integer) 2 127.0.0.1:6379[2]> rpush mylist hh3 (integer) 3 127.0.0.1:6379[2]> rpush mylist hh4 (integer) 4 127.0.0.1:6379[2]> lrange mylist 0 -1 1) "hh1" 2) "hh2" 3) "hh3" 4) "hh4" 127.0.0.1:6379[2]> ltrim mylist 1 2 //截取下标1 2的值 OK 127.0.0.1:6379[2]> lrange mylist 0 -1 1) "hh2" 2) "hh3" 127.0.0.1:6379[2]> ############################################### rpoplpush 移除列表最后一个值到另一个列表中 127.0.0.1:6379[2]> lrange mylist 0 -1 1) "hh2" 2) "hh3" 127.0.0.1:6379[2]> rpoplpush mylist myotherlist//移动最后值到新的列表 "hh3" 127.0.0.1:6379[2]> lrange mylist 0 -1 1) "hh2" 127.0.0.1:6379[2]> lrange myotherlist 0 -1 //查看新的列表中的值 1) "hh3" 127.0.0.1:6379[2]> ########################################## lset 将列表中指定下标的值替换另一个值 127.0.0.1:6379[2]> exists list (integer) 0 127.0.0.1:6379[2]> lpush list value (integer) 1 127.0.0.1:6379[2]> lrange list 0 0 1) "value" 127.0.0.1:6379[2]> lset list 0 item //替换下标为0的值 OK 127.0.0.1:6379[2]> lrange list 0 0 1) "item" 127.0.0.1:6379[2]> ############################################### linsert 将某个元素value插入列表中某个元素的前面或者后面 127.0.0.1:6379[2]> rpush mylist hello (integer) 1 127.0.0.1:6379[2]> rpush mylist world (integer) 2 127.0.0.1:6379[2]> lrange mylist 0 -1 1) "hello" 2) "world" 127.0.0.1:6379[2]> linsert mylist after world welcome //world后面插入值welcome (integer) 3 127.0.0.1:6379[2]> lrange mylist 0 -1 1) "hello" 2) "world" 3) "welcome" 127.0.0.1:6379[2]> linsert mylist before world new //world前面插入值new (integer) 4 127.0.0.1:6379[2]> lrange mylist 0 -1 1) "hello" 2) "new" 3) "world" 4) "welcome" 127.0.0.1:6379[2]>
正常执行事务 127.0.0.1:6379[2]> multi //开启事务 OK 127.0.0.1:6379[2](TX)> set k1 v1 //设置元素入队 QUEUED 127.0.0.1:6379[2](TX)> set k2 v2 QUEUED 127.0.0.1:6379[2](TX)> get k2 QUEUED 127.0.0.1:6379[2](TX)> set k3 v3 QUEUED 127.0.0.1:6379[2](TX)> exec //执行事务 1) OK 2) OK 3) "v2" 4) OK 127.0.0.1:6379[2]> ############################################## 放弃事务 127.0.0.1:6379[2]> keys * 1) "k4" 2) "k2" 3) "k1" 4) "k3" 127.0.0.1:6379[2]> multi OK 127.0.0.1:6379[2](TX)> set k5 v5 QUEUED 127.0.0.1:6379[2](TX)> discard //退出当前事务 OK 127.0.0.1:6379[2]> get k5 (nil) 127.0.0.1:6379[2]>
编译型异常(代码有问题),事务中所有的命令都不会执行
127.0.0.1:6379[2]> multi //开启事务 OK 127.0.0.1:6379[2](TX)> set k1 v1 //入队操作 QUEUED 127.0.0.1:6379[2](TX)> set k2 v2 QUEUED 127.0.0.1:6379[2](TX)> getset k2 (error) ERR wrong number of arguments for 'getset' command //出现问题 127.0.0.1:6379[2](TX)> set k3 v3 QUEUED 127.0.0.1:6379[2](TX)> exec //执行事务 (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379[2]> get k3 //所有命令都不会执行 (nil) 127.0.0.1:6379[2]>
127.0.0.1:6379[2]> set k1 v1 OK 127.0.0.1:6379[2]> multi OK 127.0.0.1:6379[2](TX)> incr k1 //命令出错 QUEUED 127.0.0.1:6379[2](TX)> set k2 v2 QUEUED 127.0.0.1:6379[2](TX)> set k3 v3 QUEUED 127.0.0.1:6379[2](TX)> exec 1) (error) ERR value is not an integer or out of range 2) OK 3) OK 127.0.0.1:6379[2]> get k2 //其他命令正常执行 "v2" 127.0.0.1:6379[2]>
监控 watch
悲观锁:
很悲观,认为什么时候都会出问题,无论做什么都会加锁。
乐观锁:
很乐观,认为什么时候都不会出问题,所以不会上锁,在更新数据的时候会判断,在此期间是否有人修改了数据
获取version
更新的时候比较version
redis 监视测试
正常执行 127.0.0.1:6379[2]> set money 100 OK 127.0.0.1:6379[2]> set out 0 OK 127.0.0.1:6379[2]> watch money //监视money对象 ok 127.0.0.1:6379[2]> multi //开启事务 OK 127.0.0.1:6379[2](TX)> decrby money 20 //减去20 QUEUED 127.0.0.1:6379[2](TX)> incrby out 20 //增加20 QUEUED 127.0.0.1:6379[2](TX)> exec //执行事务 1) (integer) 80 2) (integer) 20 127.0.0.1:6379[2]> get money "80" 127.0.0.1:6379[2]> get out "20" 127.0.0.1:6379[2]>
测试多线程修改值,使用watch可以当做redis的乐观锁操作
线程一 1) (integer) 70 2) (integer) 30 127.0.0.1:6379[2]> watch money //监视money OK 127.0.0.1:6379[2]> multi OK 127.0.0.1:6379[2](TX)> decrby money 10 QUEUED 127.0.0.1:6379[2](TX)> incrby money 10 QUEUED 127.0.0.1:6379[2](TX)> exec //执行之前,另一个线程修改了值,就会导致事务执行失败 (nil) 127.0.0.1:6379[2]> get money //修改后的值 "200" 127.0.0.1:6379[2]> get out "30" 127.0.0.1:6379[2]> ############################################# 另一个线程修改了值(在exec事务执行前) 127.0.0.1:6379[2]> set money 200 OK 127.0.0.1:6379[2]>
监视失败,重新监视新的值
127.0.0.1:6379[2]> UNWATCH //如果失败,先解锁 OK 127.0.0.1:6379[2]> watch money //重新监视 OK 127.0.0.1:6379[2]> multi //开启事务 OK 127.0.0.1:6379[2](TX)> decrby money 10 QUEUED 127.0.0.1:6379[2](TX)> incrby out 10 QUEUED 127.0.0.1:6379[2](TX)> exec //执行事务 1) (integer) 190 2) (integer) 40 127.0.0.1:6379[2]>
bind 127.0.0.1 -::1 //本机ip protected-mode yes //保护模式 port 6379 //端口
通用
daemonize yes //守护线程,默认是no,手动开启 pidfile /var/run/redis_6379.pid //后台方式运行,需要一个pid文件 ####日志 # Specify the server verbosity level. # This can be one of: # debug (a lot of information, useful for development/testing) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) # warning (only very important / critical messages are logged) loglevel notice logfile "" //日志的文件夹位置 databases 16 //数据库数量,默认16 always-show-logo no //是否显示logo
快照
持久化,在规定的时间内,执行了多少次操作,则会持久化到文件.rdb .aof中
save 3600 1 //3600s内,至少一个key发生了变化,会进行持久化操作 300 100 60 10000 stop-writes-on-bgsave-error yes //持久化出错,是否继续工作 rdbcompression yes //是否压缩rdb文件 rdbchecksum yes //保存rdb文件,进行检查 dir ./ //rdb文件保存的目录