目录
# Redis简介
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统,是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。一款高性能的NOSQL系列的非关系型数据库,非关系型数据库还有MongoDB,Membase等。关系型有 mysql 和oracle等。c语言开发。
特征:
基于内存的、非关系型的缓存和数据库,用的是epoll机制。每次客户端调用都经历了发送命令、执行命令、返回结果三个过程,所有命令都会进入一个队列中。
work线程是单线程,相对于mysql的串行化数据隔离级别相比,中间加一层redis 相对会变快,比如下面的从c1和c2客户端两个客户端同事请求数据,两者是串行的。
新版:增加了多线程的io操作(io threads),就是把read和write放在多线程处理,而redis的work线程只是负责计算操作来保证顺序。
二进制安全的:不会改变你的数值,你要提供字节数组,这在设置key value的时候redis自己做了。
弊端:单线程工作,不能发挥硬件优势,对于一些冷数据(热数据是指频繁操作的数据),如果放在内存中基本上是对内存的一种浪费。单线程会有一个问题:对于每个命令的执行时间是有要求的。如果 某个命令执行过长,会造成其他命令的阻塞,对于Redis这种高性能的服务 来说是致命的,所以Redis是面向快速执行场景的数据库。
那么为什么Redis使用单线程模型会达到每秒万级别的处理能力呢?可以将其归结为三点:
第一,纯内存访问,Redis将所有数据放在内存中,内存的响应时长大 约为100纳秒,这是Redis达到每秒万级别访问的重要基础。
第二,非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现,再加上 Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间。
第三,单线程避免了线程切换和竞态产生的消耗。
与memcached相比:
memcached的值为String, 可以通过Json来序列化反序列化对象。数据向计算移动(就是把整个数据取出来发送过去,然后解析自己想要的)。memcache服务器在编译安装的时候默认是单线程应用,如果你想变成支持多线程的,那么编译的时候指定./configure --enable-threads就可以编译成支撑多线程的应用程序了。主要是为了现在的多核系统准备的。但是官方文档也明说了,你的机器必须支持多线程编程,否则还是用不了那个memcache的多线程模式
Redis有5种数据类型,而且还有本地方法,比如list的index方法,不用返回整个数据,导致IO减小,计算向数据移动(先解析想要的,然后把需要的一小部分数据发送过去),redis的计算发生在redis内部。
关系型数据库与非关系型数据库对比:两者互补,通常情况下,使用关系型数据库,在合适的时候使用Nosql数据库,一般会将数据存储在关系型数据库,在Nosql数据库中备份存储关系型数据库的数据。
Redis使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
Redis 与其他 key - value 缓存产品有以下特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
- 速度快,读写达到10万/秒。
- 很多存储系统和编程语言内部使用CAS机制实现计数功能,会有一定的 CPU开销,但在Redis中完全不存在这个问题,因为Redis是单线程架构,任 何命令到了Redis服务端都要顺序执行。
# 安装
https://www.cnblogs.com/arxive/p/9301512.html
命令操作
https://www.redis.net.cn/tutorial/3509.html
1.Redis的数据结构:redis存储的是key,value格式的数据,其中key都是字符串,value有5中不同的数据结构
value的数据结构:object encoding key 查看key的编码
1)字符串类型string :value最大512M
set key value [ex seconds] [px milliseconds] [nx|xx]
·ex seconds:为键设置秒级过期时间。
·px milliseconds:为键设置毫秒级过期时间。
·nx:键必须不存在,才可以设置成功,用于添加。
·xx:与nx相反,键必须存在,才可以设置成功,用于更新。
get key
getset key value 设置并返回原值
del key 成功返回1 失败返回0
STRLEN key 返回 是 value的字节数。字节数跟编码有关。
APPEND Key value 扩展value
bittop and key3 key1 key2 :二进制的与操作。把key1和key2按位与后的结果放在key3里。 or是或操作。
psetex key milliseconds value 以毫秒为单位设置过期时间
setex key seconds value ,将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位) ,不但是原子执行,同时减少了一次网络通讯的时间。
setnx 只有在 key 不存在时设置 key 的值
mset key value [key value …] 批量设置值 mset a 1 b 2 c 3 d 4
mget key [key …] 批量获取值 mget a b c d 如果有些键不存在,那么它的值为nil(空),mget 为 一次get多个 ,要比get n次 更有效率,但如果数量过多可能造成Redis阻塞或者网络拥塞。mget和mset虽然是批量的,但是是一个命令,是一个原子命令。
INCR 可以对 数值进行 数值操作
incr 会有三种情况
·值不是整数,返回错误。
·值是整数,返回自增后的结果。
·键不存在,按照值为0自增,返回结果为1。
Redis还提供了decr(自减)、incrby(自增指定数字)、 decrby(自减指定数字)、incrbyfloat(自增浮点数):
decr key ;incrby key increment ;decrby key decrement ;incrbyfloat key increment
setbit key offset value(0或1) 设置key的二进制从左往右偏移offset 位 并设置为 value
bitcount key start end (start 和end 为开始和结束的字节下标索引) : 统计key的value 的 start 到end 的 1 的个数 。end 可以为-1 。 0 到 -1 为统计所有字节。
但其编码方式可以是int、raw或者embstr,区别在于内存结构的不同
**int:**字符串保存的是整数值,并且这个正式可以用long类型来表示,那么其就会直接保存在redisObject的ptr属性里,并将编码设置为int
**raw:**字符串保存的大于32字节的字符串值,则使用简单动态字符串(SDS)结构,并将编码设置为raw,此时内存结构与SDS结构一致,内存分配次数为两次,创建redisObject对象和sdshdr结构
**embstr:**字符串保存的小于等于32字节的字符串值,使用的也是简单的动态字符串(SDS结构),但是内存结构做了优化,用于保存顿消的字符串;内存分配也只需要一次就可完成,分配一块连续的空间即可,
- 在Redis中,存储long、double类型的浮点数是先转换为字符串再进行存储的。
- raw与embstr编码效果是相同的,不同在于内存分配与释放,raw两次,embstr一次。
- embstr内存块连续,能更好的利用缓存在来的优势
- int编码和embstr编码如果做追加字符串等操作,满足条件下会被转换为raw编码;embstr编码的对象是只读的,一旦修改会先转码到raw
2)哈希类型 hash map格式 :ziplist和hashtable编码
hset key field value: field value 为 hashmap的键值。
hget key field
hgetall key 获取指定key的所有filed和value。 如果哈希元素个数比较多,会存在阻塞Redis的可能。
hdel key field [field …] hdel会删除一个或多个field,返回结果为成功删除field的个数。
hlen key 计算field个数
批量设置或获取field-value
hmget key field [field …]
hmset key field value [field value …]
hexists key field 判断field是否存
hkeys key 获取所有field hvals key 获取所有value
hincrby和hincrbyfloat,就像incrby和incrbyfloat命令一样,但是它们的作 用域是filed。
hincrby key field increment
hincrbyfloat key field increment
hstrlen key field 计算value的字符串长度(需要Redis3.2以上)
ziplist编码的哈希对象底层实现是压缩列表,在ziplist编码的哈希对象中,key-value键值对是以紧密相连的方式放入压缩链表的,先把key放入表尾,再放入value;键值对总是向表尾添加。
hashtable编码的哈希对象底层实现是字典,哈希对象中的每个key-value对都使用一个字典键值对来保存。
哈希对象使用ziplist编码需要满足两个条件:当哈希类型元素个数小于hash-max-ziplist-entries 配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64 字节)
不满足任意一个都使用hashtable编码。而 hashtable的读写时间复杂度为O(1)。
3)列表类型 list :列表对象的编码可以是ziplist和linkedlist之一。一个列表最多可以存储2^32-1个元素
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)
lpush(从列表左边添加)lpush key value [value …]
rpush (从列表右边添加) rpush key value [value …]
llen key 获取列表长度
lset key index newValue 修改指定索引下标的元素
lrange key start end 范围获取, 查看所有 范围从0 到 -1
lpop 删除列表最左边的元素并返回, lpop key
rpop 删除列表最又边的元素并返回, lpop key
lrem key count value ,lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:
·count>0,从左到右,删除最多count个元素。
·count<0,从右到左,删除最多count绝对值个元素。
·count=0,删除所有
ltrim key start end 按照索引范围修剪列表 比如 ltrim listkey 1 操作会只保留列表listkey第2个到第4个元素。
lindex key index 获取列表对应索引的元素。 lindex listkey -1 当前列表最后一个元素
linsert key before|after pivot value linsert 命令会从列表中找到等于pivot的元素,在其前(before)或者后 (after)插入一个新的元素value. 返回结果为list的长度,
阻塞式弹出如下:blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用 方法基本相同。key[key…]:多个列表的键,·timeout:阻塞时间(单位:秒)。
blpop key [key …] timeout
brpop key [key …] timeout
1)列表为空:如果timeout=3,那么客户端要等到3秒后返回,如果 timeout=0,那么客户端一直阻塞等下去:如果此期间添加了数据element1,客户端立即返回。
2)列表不为空:客户端会立即返回。
在使用brpop时,有两点需要注意:
第一点,如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端立即返回。
第二点,如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取到弹出的值,其他顺序执行。
linkedlist编码底层采用双端链表实现,每个双端链表节点都保存了一个字符串对象,在每个字符串对象内保存了一个列表元素。
列表对象使用ziplist编码需要满足两个条件:一是所有字符串长度都小于64字节,二是元素数量小于512,不满足任意一个都会使用linkedlist编码。
两个条件的数字可以在Redis的配置文件中修改,list-max-ziplist-value选项和list-max-ziplist-entries选项。
使用场景:lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令 阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用
性。
·lpush+lpop=Stack(栈)
·lpush+rpop=Queue(队列)
·lpsh+ltrim=Capped Collection(有限集合)
·lpush+brpop=Message Queue(消息队列)
4)集合类型 set 不允许重复值(不推荐使用),需要用数据太多,比如下面的srandmember操作需要随机 ,阻塞带宽。
intset和hashtable编码。
sadd key element [element …] 存储 成功返回1 失败返回0
smembers key 获取set中的所有元素,smembers和lrange、hgetall都属于比较重的命令,如果元素过多存在阻 塞Redis的可能性
srem key element [element …] 删除集合中的元素
scard key 计算元素个数 ,scard的时间复杂度为O(1),它不会遍历集合所有元素,而是直接用 Redis内部的变量。
sismember key element 判断元素是否在集合, 在集合内返回1,反之返回0
srandmember key n: 如果n为整数(不写 默认1),随机获取n个不重复元素,如果大于集合个数,那就返回所有元素。如果n小于0.那么返回可以重复元素,如果abs(n)大于元素个数仍然可以返回随机的n个可以重复元素。
spop key ,spop操作可以从集合中随机弹出一个元素 ,spop也支持[count]参数。srandmember和spop都是随机从集合选出元素,两者不同的是spop命令 执行后,元素会从集合中删除,而srandmember不会。
sinter key [key …] 交集
suinon key [key …] 并集
sdiff key [key …] 差集 key1 key2谁在前取谁的差集
集合间的运算在元素较多的情况下会比较耗时,所以Redis提供了上面 三个命令(原命令+store)将集合间交集、并集、差集的结果保存在 destination 这个 key中
sinterstore destination key [key …]
suionstore destination key [key …]
sdiffstore destination key [key …]
intset编码的集合对象底层实现是整数集合,所有元素都保存在整数集合中
集合对象使用intset编码需要满足两个条件:一是所有元素都是整数值;二是元素个数小于等于512个;不满足任意一条都将使用hashtable编码。
以上第二个条件可以在Redis配置文件中修改et-max-intset-entries选项
5)有序集合类型sortedset :不允许重复元素,且元素有序,ziplist编码 和skiplist编码
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
存储:zadd key score member [score member …] 重复zadd会更新score 小的靠前 ,返回结果代表成功添加成员的个数
为zadd命令添加了nx、xx、ch、incr四个选项:
·nx:member必须不存在,才可以设置成功,用于添加。
·xx:member必须存在,才可以设置成功,用于更新。
·ch:返回此次操作后,有序集合元素和分数发生变化的个数
·incr:对score做增加,相当于后面介绍的zincrby。
zrem key member [member …] 删除成员 ,返回结果为成功删除的个数。
zcard key 计算成员个数
zscore key member 计算某个成员的分数
计算成员的排名: zrank是从分数从低到高返回排名,zrevrank反之
zrank key member
zrevrank key member
有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间 复杂度为O(log(n)),sadd的时间复杂度为O(1)。
zincrby key increment(增加的值) member 增加成员的分数
获取:zrange key start end 0到-1为所有 zrange key 0 -1 withscores 并列出soce . 从小到大。
zrevrange key start end 从大到小 zrevrange key 0 1 倒序取两个
返回指定分数范围的成员:其中zrangebyscore按照分数从低到高返回,zrevrangebyscore反之,withscores选项会同时返回每个 成员的分数。[limit offset count]选项可以限制输出的起始位置和个数,同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和 +inf分别代表无限小和无限大:
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
zrevrangebyscore user:ranking 221 200 withscores
zrangebyscore user:ranking (200 +inf withscores
zcount key min max 返回指定分数范围成员个数
zremrangebyrank key start end 删除指定排名内的升序元素 zremrangebyrank user:ranking 0 2
zremrangebyscore key min max 删除指定分数范围的成员 zremrangebyscore user:ranking (250 +inf
交集:
zinterstore destination numkeys key [key …] [weights weight [weight …]] [aggregate sum|min|max]
这个命令参数较多,下面分别进行说明:
·destination:交集计算结果保存到这个键。
·numkeys:需要做交集计算键的个数。
·key[key…]:需要做交集计算的键。
·weights weight[weight…]:每个键的权重,在做交集计算时,每个键中 的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
·aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、 min(最小值)、max(最大值)做汇总,默认值是sum
并集:
zunionstore destination numkeys key [key …] [weights weight [weight …]] [aggregate sum|min|max]
该命令的所有参数和zinterstore是一致的,只不过是做并集计算,
skiplist编码的有序集合对象底层实现是跳跃表和字典两种;
每个跳跃表节点都保存一个集合元素,并按分值从小到大排列;节点的object属性保存了元素的成员,score属性保存分值;
字典的每个键值对保存一个集合元素,字典的键保存元素的成员,字典的值保存分值。
为何skiplist编码要同时使用跳跃表和字典实现?
- 跳跃表优点是有序,但是查询分值复杂度为O(logn);字典查询分值复杂度为O(1) ,但是无序,所以结合连个结构的有点进行实现。
- 虽然采用两个结构但是集合的元素成员和分值是共享的,两种结构通过指针指向同一地址,不会浪费内存。
有序集合对象使用ziplist编码需要满足两个条件:一是所有元素长度小于64字节;二是元素个数小于128个;不满足任意一条件将使用skiplist编码。
以上两个条件可以在Redis配置文件中修改zset-max-ziplist-entries选项和zset-max-ziplist-value选项
总结:
在Redis的五大数据对象中,string对象是唯一个可以被其他四种数据对象作为内嵌对象的;
列表(list)、哈希(hash)、集合(set)、有序集合(zset)底层实现都用到了压缩列表结构,并且使用压缩列表结构的条件都是在元素个数比较少、字节长度较短的情况下;
四种数据对象使用压缩列表的优点:
(1)节约内存,减少内存开销,Redis是内存型数据库,所以一定情况下减少内存开销是非常有必要的。
(2)减少内存碎片,压缩列表的内存块是连续的,并分配内存的次数一次即可。
(3)压缩列表的新增、删除、查找操作的平均时间复杂度是O(N),在N再一定的范围内,这个时间几乎是可以忽略的,并且N的上限值是可以配置的。
(4)四种数据对象都有两种编码结构,灵活性增加。
通用命令:
1.keys * 遍历查询所有的键 ,所以它的时间复杂度是O(n),当Redis保存了大量键时,线上环境禁止使用。支持pattern匹配,
*代表匹配任意字符
·代表匹配一个字符
[]代表匹配部分字符,例如[1,3]代表匹配1,3,[1-10]代表匹配1到10
的任意数字。
·\x用来做转义,例如要匹配星号、问号需要进行转义。
和keys命令执行时会遍历所有键不同,scan采用渐进式遍历 的方式来解决keys命令可能带来的阻塞问题,每次scan命令的时间复杂度是 O(1),但是要真正实现keys的功能,需要执行多次scan。那么每次执行scan,可以想象成只扫描一个字典中的一部分键,直到将 字典中的所有键遍历完毕。scan的使用方法如下:
scan cursor [match pattern] [count number]
·cursor是必需参数,实际上cursor是一个游标,第一次遍历从0开始,每 次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束。
·match pattern是可选参数,它的作用的是做模式的匹配,这点和keys的
模式匹配很像。
·count number是可选参数,它的作用是表明每次要遍历的键个数,默认 值是10,此参数可以适当增大。
现有一个Redis有26个键(英文26个字母),现在要遍历所有的键,使 用scan命令效果的操作如下。第一次执行scan0,返回结果分为两个部分:第 一个部分6就是下次scan需要的cursor,第二个部分是10个键:
127.0.0.1:6379> scan 0
-
“6”
-
- “w” 2) “i” 3) “e” 4) “x” 5) “j” 6) “q” 7) “y” 8) “u” 9) “b” 10) “o”
使用新的cursor=“6”,执行scan6
127.0.0.1:6379> scan 6
-
“11”
-
- “h” 2) “n” 3) “m” 4) “t” 5) “c” 6) “d” 7) “g” 8) “p” 9) “z” 10) “a”
这次得到的cursor=“11”,继续执行scan11得到结果cursor变为0,说明所有的键已经被遍历过了:
127.0.0.1:6379> scan 11
-
“0”
-
- “s” 2) “f” 3) “r” 4) “v” 5) “k” 6) “l”
除了scan以外,Redis提供了面向哈希类型、集合类型、有序集合的扫 描遍历命令,解决诸如hgetall、smembers、zrange可能产生的阻塞问题,对 应的命令分别是hscan、sscan、zscan,它们的用法和scan基本类似。渐进式遍历可以有效的解决keys命令可能产生的阻塞问题,但是scan并 非完美无瑕,如果在scan的过程中如果有键的变化(增加、删除、修改),那么遍历效果可能会碰到如下问题:新增的键可能没有遍历到,遍历出了重 复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键,这些是我们在开发时需要考虑的。
2.dbsize命令会返回当前数据库中键的总数,dbsize命令在计算键总数时不会遍历所有键,而是直接获取Redis内置的 键总数变量,所以dbsize命令的时间复杂度是O(1)。
3.type key 获取键对应的value的类型type命令实际返回的就是当前键的数据结构类型,它们分别是: string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集 合),但这些只是Redis对外的数据结构。如果键不存在,则返回none。
4.del key [key …] 删除指定的key ,不论value为什么类型,返回结果为成功删除键的个数,假设删除一个不存在的键,就会返回
0。
5.exists key 检查键是否存在 如果键存在则返回1,不存在则返回0。
6.expire key seconds 键过期 Redis支持对键添加过期时间,当超过过期时间后,会自动删除键,例 如为键hello设置了10秒过期时间: expire hello 10,
expireat key timestamp 键在秒级时间戳timestamp后过期。
pexpire key milliseconds:键在milliseconds毫秒后过期。
pexpireat key milliseconds-timestamp键在毫秒级时间戳timestamp后过期。
但无论是使用过期时间还是时间戳,秒级还是毫秒级,在Redis内部最 终使用的都是pexpireat
在使用Redis相关过期命令时,需要注意以下几点。
1)如果expire key的键不存在,返回结果为0:
2)如果过期时间为负值,键会立即被删除,犹如使用del命令一样
3)persist命令可以将键的过期时间清除: persist key
7.ttl命令会返回键的剩余过期时间,它有3种返回值:大于等于0的整数:键剩余的过期时间。-1:键没设置过期时间。-2:键不存在。pttl也可以查询键的剩余过期时间,但是pttl精度更高可以达到 毫秒级别。
8.object encoding命令查询内部编码:每个类型有两种内部编码。
9.rename key newkey 键重命名 ,如果在rename之前,键java已经存在,那么它的值也将被覆盖,为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey 不存在时候才被覆盖,由于重命名键期间会执行del命令删除旧的键,如果键对应的值比较 大,会存在阻塞Redis的可能性,这点不要忽视
migrate命令:migrate命令也是用于在Redis实例间进行数据迁移的,实际上migrate命 令就是将dump、restore、del三个命令进行组合,从而简化了操作流程。 migrate命令具有原子性,而且从Redis3.0.6版本以后已经支持迁移多个键的 功能,有效地提高了迁移效率,migrate在10.4节水平扩容中起到重要作用。
整个过程如图2-28所示,实现过程和dump+restore基本类似,但是有3点 不太相同:第一,整个过程是原子执行的,不需要在多个Redis实例上开启 客户端的,只需要在源Redis上执行migrate命令即可。第二,migrate命令的 数据传输直接在源Redis和目标Redis上完成的。第三,目标Redis完成restore 后会发送OK给源Redis,源Redis接收后会根据migrate对应的选项来决定是否 在源Redis上删除对应的键。
下面对migrate的参数进行逐个说明:
host:目标Redis的IP地址。
port:目标Redis的端口。
key|"":在Redis3.0.6版本之前,migrate只支持迁移一个键,所以此处是 要迁移的键,但Redis3.0.6版本之后支持迁移多个键,如果当前需要迁移多 个键,此处为空字符串""。
destination-db:目标Redis的数据库索引,例如要迁移到0号数据库,这里就写0。
timeout:迁移的超时时间(单位为毫秒)。
[copy]:如果添加此选项,迁移后并不删除源键。
[replace]:如果添加此选项,migrate不管目标Redis是否存在该键都会正常迁移进行数据覆盖。
[keys key[key…]]:迁移多个键,例如要迁移key1、key2、key3,此处填 写“keys key1 key2 key3”
比如:migrate 127.0.0.1 6380 “” 0 5000 keys key1 key2 key3
move命令用于在Redis内部进行数据迁移,Redis内部可以有多个数据库,Redis内部可以有多个数据库,彼此在数据上是相互隔离的,move key db就是把指定的键从源数据库移动到目标数据库中,不建议在生产环境使用。
建议使用migrate命令进行键值迁移。
Redis提供了几个面向Redis数据库的操作,它们分别是dbsize、select、 flushdb/flushall命令,本节将通过具体的使用场景介绍这些命令。
select dbIndex 切换数据库 , Redis默认配置中是有16个数据库,select 0操作将切换到第一个数据库,select 15选择最 后一个数据库,但是0号数据库和15号数据库之间的数据没有任何关联,甚至可以存在相同的键。当使用rediscli-h{ip}-p{port}连接Redis时,默认使用的就是0号数据库,当选择其他数据 库时,会有[index]的前缀标识,其中index就是数据库的索引下标。Redis3.0中已经逐渐弱化这个功能,例如Redis的分布式实现Redis Cluster只允许使用0号数据库,只不过为了向下兼容老版本的数据库功能, 为什么要废弃掉这个“优秀”的功能呢?总结起来有三点:
Redis是单线程的。如果使用多个数据库,那么这些数据库仍然是使用 一个CPU,彼此之间还是会受到影响的。
多数据库的使用方式,会让调试和运维不同业务的数据库变的困难,假如有一个慢查询存在,依然会影响其他数据库,这样会使得别的业务方定位问题非常的困难
部分Redis的客户端根本就不支持这种方式。即使支持,在开发的时候来回切换数字形式的数据库,很容易弄乱。
flushdb/flushall命令用于清除数据库,两者的区别的是flushdb只清除当 前数据库,flushall会清除所有数据库。flushdb/flushall命令会将所有数据清除,一旦误操作后果不堪设想。
Bitmaps
Redis提供了Bitmaps这个“数据结构”可以实现对位的操作。。把数据结构加上引号主要因为:Bitmaps本身不是一种数据结构