
使用help查询有哪些命令
示例所有Key名都为bigkang为示例
首先我们需要了解什么是Bit,其实所有的Bit *** 作都是在 *** 作字符串类型,我们设置了bit以后可以发现他的类型其实是一个String
然后我们来获取这个bit的类型
那么我们就会发现其实存储的数据是一个字符串,那么字符串和bit有什么关系呢,我们知道Redis中的字符串底层采用的SDS,实际上它存储的一个char数组,那么这个char数组,那么C语言中一个char等于1个byte,一个byte等于8个bit,我们可以知道一个char能够存储8个bit,那么Redis的String能够存储512MB,那么我们再来看一下最大能够存储多少个bit位:
最大存储数量
512 1024 1024 8 = 42 9496 7296 (大约43亿)
MB KB Byte BIit
我们就能够存储大约43亿bit,每个bit的值只能是0 或者 1
我们上访的 *** 作 setbit newbit 1 1 就是将bit位为1,也就是第二个bit设置为1,bit为数组
大概的流程图如下:
这样我们就可以知道bit位在 0 - 7的属于第一个字节,8 - 15属于第二个字节,那么我们现在来测试一下吧
例如我们想要获取某个bit位的值,我们使用getbit
BitCount可以统计我们的Bit数组中的值为1的数据,例如我想要统计bit位的值的结果有多少。(!注意是根据一个char,也就是一个byte=8bit进行统计,每个值表示相应的8个bit)
如下
或者根据范围进行统计
Bit主要用来帮助我们对不同Bit进行 *** 作,和Set中的并集,并归等类似。
现在我们来初始化两个bit数据
目前两个Bit中的结构如下
那么我们知道既然是二进制,那么肯定是有运算的,例如与,或等等
Redis提供了如下几种
AND
OR
NOT
XOR
Bit *** 作可以帮助我们存储大量的数据,以及状态,我们可以在多个场景下使用,例如用户的连续登录,以及活跃用户统计。
例如如下 *** 作,我们的Key采用 login-年-月-日 ,bit位 使用用户ID,状态为1
Redis基于Request/Response 协议。通常情况下一次请求的步骤如下
1 客户端通过tcp 协议发送指令到服务端,等待redis服务端返回结果
2 redis服务端执行命令,返回响应到客户端。
客户端发送请求到接受到服务端返回的响应被称为一次RTT(Round Trip Time) 在不考虑redis 服务端处理耗时的情况下,数据传输的耗时是最要的开销。且redis client 必须等待上一次响应结果才能发送下一个指令,会长时间处于阻塞的状态。
为解决提升reids服务端的吞吐量,redis提供了如下几种解决方案。
redis实现了HMGET/HMSET/MSET/MGET等一系列批量指令。区别与普通指令如GET, MGET可以一次性发送key数组,然后redis服务端一次性返回结果数组。
很明显这种方式可以使用一次RTT处理完多个指令。这种方式的在性能上是最好的,缺点在于
1 指令类型必须一致,批量指令依赖于Redis的实现,有些指令如setbit 没有批量实现的,就无法使用这种方案。
2 不能混合指令发送,需要发送的指令必须在一次请求中确定。灵活性比pipeline差。
pipelining 是Request/Reponse协议的一种实现方式。客户端连续发送请求,而不用等待上一次的response返回。最终通过一次读取之前所有的Response。Redis服务支持这种实现方式。
我们通过redis-benchmark对比下普通cs模型和pipleline的性能。
从上面测试结果可以看出pipleline的性能远高于普通的请求方式。
1 pipeline的RTT交互次数,从而减少延迟,在网络延迟比较大的环境下。吞吐量提高会特别明显。
2 redis客户端/服务端减少了sys_call调用次数,减少了用户态到内核态的切换开销。
3 redis客户端发送无需等待上一次response请求结果,减少了阻塞时间。
Pipelining is not just a way in order to reduce the latency cost due to the round trip time, it actually improves by a huge amount the total operations you can perform per second in a given Redis server This is the result of the fact that, without using pipelining, serving each command is very cheap from the point of view of accessing the data structures and producing the reply, but it is very costly from the point of view of doing the socket I/O This involves calling the read() and write() syscall, that means going from user land to kernel land The context switch is a huge speed penalty
Redis-Bloomfilter在100版本时, *** 作redis是基于标准的request/response模式, 但是Bloomfilter 在精度和预计插入数量大的情况,需要做多次hash *** 作。这样一次bloomfilter *** 作需要进行几十次redis setbit/getbit。这种情况下会严重影响Bloomfilter的吞吐量。由于setbit/getbit 不支持批量 *** 作,所以采用pipeline来优化redis的性能开销。具体可以参考 >
在SpringBoot项目中,通过RBuckets接口实现批量 *** 作对个Bucket对象,示例如下:
方法介绍:
多个连续命令可以通过RBatch对象在一次网络会话请求里合并发送,这样省去了产生多个请求消耗的时间和资源。这在Redis中叫做管道。
RBatch管道功能就是REDIS的批量发送,实际上是客户端的功能,与服务端无关。相当于把多个请求的命令放在一个数据包通过TCP发送到服务端,然后客户端再一次性读取所有的命令回应。管道技术最显著的优势是提高了 redis 服务的性能。
执行batchDemo()后,控制台打印结果如下:
测试用例主要介绍了Hash,当然RBatch还支持List、Set、对象桶、队列、发布订阅等。
顺便介绍一下Redis中Map的使用场景
在集群模式下,所有的命令会按各个槽所在的节点,筛选分配到各个节点并同时发送。每个节点返回的结果将会汇总到最终的结果列表里。上述demo中用到的工具类如下:
参考:
>
我们知道Redis默认有16个数据库,默认是第0个数据库,那么如果在需要对数据库进行切换的时候,我们就可以使用下面这个命令:
使用如下命令进行切换
如果想要清除指定某一个数据库的数据
清除所有数据库的数据
接下来这个命令应该是最常用的了
平常在开发中,我们还需要经常对key进行判断,判断其是否存在
因为我们设置的缓存数据一般都不能是永久的,这个时候就需要我们在存储数据的时候,就为其设置过期时间。
string类型是Redis中五大基本数据类型之一,这也是最常使用到的一个数据类型,所有很多小伙伴们对Redis的认识和 *** 作就仅仅的停留在了对Redis的 *** 作层面,但是你是否知道string类型中的相关命令,还是有非常多实用的
接下来先看一下对string类型进行基本存储和获取的命令。
如果我们存储的string中的内容是数字的话,我们也可以对其进行增或减 *** 作,Redis可以自动的对字符串进行相关的 *** 作。实现的命令如下:
使用msetnx时,同时设置一个或多个 key-value 对,当且仅当所有给定 key都不存在时才成立。
getset命令从字面意思就可以看出来,他的作用是先get再set。
总结string类似的使用场景:
在使用list类型进行存取的时候,有两个命令需要进行区分:
注意:只有pop和push才分左右,其他的l都是list的意思
总结:
总结set集合一般用于元素的不重复的场景,比如抽奖系统,轮播等场景下
在使用hash集合的时候,要注意,hash其实就是一个Map集合,key-map的时候,值是一个map集合的形式进行存储的,也和Java中的hashmap有一个类似。
HVALS获取所有的value,HKEYS获取所有的key,HGETALL获取所有的键值
总结:
hash可以用于存储变更的数据,比如user,name,age等,尤其是用户信息之类的,hash更加适合用于对象的存储,string更加适合用于字符串的存储。
在set集合的基础上增加一个序列号,来进行排序
ZRANGEBYSCORE使用语法
总结
以上是在对五种数据类型进行存取时的一些常用命令 *** 作。关于其他的命令使用,小伙伴们在用到的时候可以直接入官网查看就可以了。
-r(repeat)选项代表将命令执行多次,例如下面 *** 作将会执行三次ping
命令:
redis-cli -r 3 ping
PONG
PONG
PONG
-i(interval)选项代表每隔几秒执行一次命令,但是-i选项必须和-r选 项一起使用,下面的 *** 作会每隔1秒执行一次ping命令,一共执行5次:
注意-i的单位是秒,不支持毫秒为单位,但是如果想以每隔10毫秒执行 一次,可以用-i001
redis-cli -r 5 -i 001 ping
例如下面的 *** 作利用-r和-i选项,每隔1秒输出内存的使用量,一共输出 100次
redis-cli -r 100 -i 1 info | grep used_memory_human
used_memory_human:295G
used_memory_human:295G
-x选项代表从标准输入(stdin)读取数据作为redis-cli的最后一个参 数,例如下面的 *** 作会将字符串world作为set hello的值
$ echo "world" | redis-cli -x set hello
OK
-c(cluster)选项是连接Redis Cluster节点时需要使用的,-c选项可以防 止moved和ask异常
如果Redis配置了密码,可以用-a(auth)选项,有了这个选项就不需要 手动输入auth命令
--scan选项和--pattern选项用于扫描指定模式的键,相当于使用scan命令
--slave选项是把当前客户端模拟成当前Redis节点的从节点,可以用来 获取当前Redis节点的更新 *** 作
下面开启第一个客户端,使用--slave选项,看到同步已完成:
$ redis-cli --slave
SYNC with master, discarding 72 bytes of bulk transfer
SYNC done Logging commands from master
--rdb选项会请求Redis实例生成并发送RDB持久化文件,保存在本地。 可使用它做持久化文件的定期备份
--pipe选项用于将命令封装成Redis通信协议定义的数据格式,批量发送 给Redis执行
例如下面 *** 作 同时执行了set hello world和incr counter两条命令:
echo -en '3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n2\r\n$4\r\nincr\r\ n$7\r\ncounter\r\n' | redis-cli --pipe
--bigkeys选项使用scan命令对Redis的键进行采样,从中找到内存占用比
较大的键值,这些键可能是系统的瓶颈
--eval选项用于执行指定Lua脚本,有关Lua脚本的使用将在34节介绍。
latency有三个选项,分别是--latency、--latency-history、--latency-dist。 它们都可以检测网络延迟,对于Redis的开发和运维非常有帮助。
该选项可以测试客户端到目标Redis的网络延迟,例如当前拓扑结构如 图3-4所示。客户端B和Redis在机房B,客户端A在机房A,机房A和机房B是
跨地区的
客户端B:
redis-cli -h {machineB} --latency
min: 0, max: 1, avg: 007 (4211 samples)
客户端A:
redis-cli -h {machineB} --latency
min: 0, max: 2, avg: 104 (2096 samples)
可以看到客户端A由于距离Redis比较远,平均网络延迟会稍微高一些
--latency的执行结果只有一条,如果想以分时段的形式了解延迟信息, 可以使用--latency-history选项:
redis-cli -h 1010xxxx --latency-history
min: 0, max: 1, avg: 028 (1330 samples) -- 1501 seconds range…
min: 0, max: 1, avg: 005 (1364 samples) -- 1501 seconds range
可以看到延时信息每15秒输出一次,可以通过-i参数控制间隔时间。
(3)--latency-dist
该选项会使用统计图表的形式从控制台输出延迟统计信息。
--stat选项可以实时获取Redis的重要统计信息,虽然info命令中的统计信 息更全,但是能实时看到一些增量的数据(例如requests)对于Redis的运维还是有一定帮助的
--no-raw选项是要求命令的返回结果必须是原始的格式,--raw恰恰相反,返回格式化后的结果。
在Redis中设置一个中文的value:
$redis-cli set hello "你好"
OK
如果正常执行get或者使用--no-raw选项,那么返回的结果是二进制格式:
如果使用了--raw选项,将会返回中文:
$redis-cli --raw get hello
你好
在 Redis 中查看数据可以使用以下命令:
keys pattern 命令可以列出匹配给定模式的所有键名。例如,执行 keys 可以列出所有的键名。
type key 命令可以查看指定键的数据类型。例如,执行 type mykey 可以查看键 mykey 的数据类型。
get key 命令可以获取指定键的值。例如,执行 get mykey 可以获取键 mykey 的值。
hgetall key 命令可以获取指定哈希表的所有键值对。例如,执行 hgetall myhash 可以获取哈希表 myhash 的所有键值对。
lrange key start stop 命令可以获取指定列表的一部分元素。例如,执行 lrange mylist 0 -1 可以获取列表 mylist 的所有元素。
smembers key 命令可以获取指定集合的所有成员。例如,执行 smembers myset 可以获取集合 myset 的所有成员。
zrange key start stop 命令可以获取指定有序集合的一部分成员。例如,执行 zrange myzset 0 -1 可以获取有序集合 myzset 的所有成员。
以上是 Redis 中一些基本的数据查看命令,具体使用取决于你想要查看的数据类型和数据结构。
一、故事背景
1、读取离线文件数据,再通过离线数据作为条件,查询第三方接口,返回最终的结果,再入库。
2、 业务逻辑是很简单, 读取文件、查询接口、返回数据集、入库 四步。
3、业务特性:第三方接口调用400毫秒(ms) 。
如果用普通单线程去跑算500毫秒一个请求,一天也就跑8W多数据量,20多亿的数据不知道跑到猴年马月了。
二、处理方案
A) 初步方案采用ganymed-ssh2(文件都存储在Linux服务器上) 来读文件,Redis来存储消息、多线程来提升处理能力。
B) 流程图:
三、呈现问题
四、优化问题
最终流程图:
1、 通过Redis做一个计数器 每读取一行记录数值,即使服务终止后,先从Redis读取这个数值
再通过cat指定行数开始读数据即可。
2、 通过取模拆Key 分片到不同小Key存储 ,降低单个节点存储压力,也充分利用了存储资源。
3、Redis Push 提供了批量方式(leftPushAll) ,可以指定读取行数再批量入库,而pop并没有提供批量 只能一个一个pop。
4、消费者通过多线程pop、再分发到线程去处理。
五、总结问题
MYSQL快速同步数据到Redis
举例场景:存储游戏玩家的任务数据,游戏服务器启动时将mysql中玩家的数据同步到redis中。
从MySQL中将数据导入到Redis的Hash结构中。当然,最直接的做法就是遍历MySQL数据,一条一条写入到Redis中。这样没什么错,但是速度会非常慢。如果能够想法使得MySQL的查询输出数据直接能够与Redis命令行的输入数据协议相吻合,可以节省很多消耗和缩短时间。
Mysql数据库名称为:GAME_DB, 表结构举例:
CREATE TABLE TABLE_MISSION (
playerId int(11) unsigned NOT NULL,
missionList varchar(255) NOT NULL,
PRIMARY KEY (playerId)
);
Redis中的数据结构使用哈希表:
键KEY为mission, 哈希域为mysql中对应的playerId, 哈希值为mysql中对应的missionList。 数据如下:
[root@iZ23zcsdouzZ ~]# redis-cli
127001:6379> hget missions 36598
"{\"10001\":{\"status\":1,\"progress\":0},\"10002\":{\"status\":1,\"progress\":0},\"10003\":{\"status\":1,\"progress\":0},\"10004\":{\"status\":1,\"progress\":0}}"
快速同步方法:
新建一个后缀sql文件:mysql2redis_missionsql
内容如下:
SELECT CONCAT(
"4\r\n",
'$', LENGTH(redis_cmd), '\r\n',
redis_cmd, '\r\n',
'$', LENGTH(redis_key), '\r\n',
redis_key, '\r\n',
'$', LENGTH(hkey), '\r\n',
hkey, '\r\n',
'$', LENGTH(hval), '\r\n',
hval, '\r'
)
FROM (
SELECT
'HSET' as redis_cmd,
'missions' AS redis_key,
playerId AS hkey,
missionList AS hval
FROM TABLE_MISSION
) AS t
创建shell脚本mysql2redis_missionsh
内容:
mysql GAME_DB --skip-column-names --raw < missionsql | redis-cli --pipe
Linux系统终端执行该shell脚本或者直接运行该系统命令,即可将mysql数据库GAME_DB的表TABLE_MISSION数据同步到redis中键missions中去。mysql2redis_missionsql文件就是将mysql数据的输出数据格式和redis的输入数据格式协议相匹配,从而大大缩短了同步时间。
经过测试,同样一份数据通过单条取出修改数据格式同步写入到redis消耗的时间为5min, 使用上面的sql文件和shell命令,同步完数据仅耗时3s左右。
以上就是关于Redis *** 作数据常用命令详细注释全部的内容,包括:Redis *** 作数据常用命令详细注释、Redis pipeline以及批量优化、Redisson批量 *** 作类RBuckets和管道利器RBatch等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)