目录
一、介绍
二、常用命令
2.1. set
2.2. mset
2.3. get
2.4. getset
2.5. mget
2.6. setnx
2.7. setex
2.8. msetnx
2.9. append
2.10. strlen
2.11. incr
2.12. decr
2.13. incrby/decrby
2.14. getrange
2.15. setrange
2.16. keys
2.17. exists
2.18. type
2.19. del
2.20. unlink
2.21. expire
2.22. ttl
2.23. select
2.24. dbsize
2.25. flushdb
2.26. flushall
三、Java中i++/i--与Redis的incr/decr
一、介绍
String是Redis最基本的类型,一个key对应一个value。String类型是二进制安全的,这意味着Redis的String可以包含任何数据,比如jpg图片或者序列化的对象等待。
Sring的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS),是可以修改字符串的,其内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。当字符串长度小于1M时,扩容都是加倍现有的空间;如果超过1M,扩容时一次只会多扩1M的空间,需要注意一个Redis中字符串value最多可以是512MB。
String根据字符串的格式不同,又可以分为3类:
String:普通字符串
int:整数类型,可以做自增、自减操作
float:浮点类型,可以做自增、自减操作
Redis的Key结构
Redis的key允许有多个单词形成层级结构,多个单词之间用':'隔开,格式如下:
项目名:业务名:类型:id
这个格式并非固定,也可以根据自己的需求来删除或添加词条。
例如我们的项目名称叫SanZhiYang,有user和product两种不同类型的数据,我们可以这样定义key:
user相关的key:SanZhiYang:user:1
product相关的key:SanZhiYang:product:1
二、常用命令
更详细的Redis命令操作指南,请查看Redis官网,有关命令的入口地址如下:
Commands | Docs
最好的学习方式就是阅读官方文档及源代码
2.1. set
添加键值对<key><value>
多次给同一个<key>进行set,下一次set的<value>会上一次的
2.2. mset
mset <key1><value1><key2><value2>
同时设置一个或多个<key><value>对,当第一次设置N个键值对,第二次再次去设置时,键值对数量需和上一次保持一致,否则会报错。
2.3. get
get <key> 查询key对应的值
2.4. getset
getset <key><value> 以新换旧,设置新值同时获得旧值
2.5. mget
mget <key1><key3><key3>... 同时获取一个或多个value
2.6. setnx
setnx <key><value>只有在key不存在时,设置key的值 0已存在/1不存在
2.7. setex
setex <key><过期时间><value> 设置键值的同时,设置过期时间,单位秒
2.8. msetnx
msetnx <key1><value1><key2><value2>同时设置一个或多个<key><value>对,当且仅当所有给定key都不存在时才生效,0失败/1成功。(原子性,有一个失败则都失败)
2.9. append
append <key><value>将给定的<value>追加到原值的末尾
2.10. strlen
strlen <ken> 获得指定key值的长度
2.11. incr
incr <key> 将key中储存的数字值增1,只能对数字值操作,如果为空新增值为1
2.12. decr
decr <key> 将key中储存的数字值减1,只能对数字值操作,如果为空新增值为-1
2.13. incrby/decrby
incrby/decrby <key><步长>将key中储存的数字值增减,自定义步长
2.14. getrange
getrange <key><起始位置><结束位置> 获得值的指定范围数据,类似sbustring,前包后包
2.15. setrange
setrange <key><起始位置><value> 用<value>覆写所储存的字符串值,从<起始位置>开始(索引从0开始)
2.16. keys
keys * 查看当前库所有key的值,不建议在生产环境上使用,会阻塞所有请求
2.17. exists
exists key 判断某个key是否存在 1存在/0不存在
2.18. type
type key 查看你的key是什么类型
2.19. del
del key 删除指定的key数据
2.20. unlink
unlink key 根据value选择非阻塞删除,仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作。
2.21. expire
expire key 10 给指定的key设置过期时间:十秒钟
2.22. ttl
ttl key 查看还有多少秒过期,-1表示永不过期,-2表示已过期
2.23. select
2.24. dbsize
dbsize命令查看当前数据库的key数量
2.25. flushdb
flushdb命令清空当前库
2.26. flushall
flushall命令通杀全部库
三、Java中i++/i--与Redis的incr/decr
不同于Java中的i++,这三个命令都是原子操作:
incr <key> 将key中储存的数字值增1,只能对数字值操作,如果为空新增值为1
decr <key> 将key中储存的数字值减1,只能对数字值操作,如果为空新增值为-1
incrby/decrby <key><步长>将key中储存的数字值增减,自定义步长
所谓的原子操作是指不会被线程调度机制打断的操作,一旦操作开始,就一直运行到结束,中间不会有任何context switch(切换到另一个线程)。
1. 在单线程中,能够在单条指令中完成的操作都可以认为是原子操作,因为中断只能发生于指令之间。
2. 在多线程中,不能被其它进程(线程)打断的操作就是原子操作。
Redis单命令的原子性主要得益于Redis的单线程。
Java中的i++
操作不是原子操作,这是因为i++
实际上包含三个步骤:读取当前值、将该值加一、将新值写回内存,这三个步骤并不是一次性完成的。由于这三个步骤不是在一个操作中原子性地执行,因此在多线程环境下,可能会出现数据竞争的情况,即一个线程在执行i++
操作的过程中被另一个线程打断,导致最终的结果不是预期的增加值。