infQ以及对应定制化的redis去年就开发完了,现在放出来供大家把玩一下。(infQ的介绍见 infQ——不受限于内存的队列)
1. 安装
代码地址:
infQ:https://github.com/chosen0ne/infQ.git
redis-infq:https://github.com/chosen0ne/redis-infq.git
把两个项目clone到一个目录,执行以下命令:
cd infQ
make
cd ../redis-infq
make
make成功后,和redis一样,会在redis-infq/src/目录下生成redis-server
这里注意,infQ和redis-infq一定要在同一个目录下,否则编译redis-infq时会因为找不到infQ的静态链接库而失败。
2. 支持的命令
1)qpush key value [value ... ]
将多个value添加到infQ实例中。如果key存在,但是数据类型不是infQ,返回错误Wrong Type Error。如果key不存在,会创建键为key的infQ实例。
2)qpop key
从键为key的infQ实例中pop,并返回pop出的对象。如果key不存在,返回Wrong Type Error错误。
3)qjpop key
与qpop类似,只是不会返回pop出的对象。
4)qlen key
返回键为key的infQ的实例的长度。
5)qtop key
返回键为key的infQ实例的第一个元素。
6)qdel key
删除键为key的infQ实例。
7)qat key index
返回键为key的infQ实例,在下标index对应的元素。
8)qrange key start stop
返回键为key的infQ实例,在范围[start, stop]对应的所有元素。
9)qpoprpush source destination
从键为source的infQ实例pop,并将pop出的对象rpush到键为destination的list。
3. 配置文件
默认可以通过redis-cli执行infQ相关命令,不过由于各种语言的redis客户端并不支持infQ,所以为了支持infQ,需要将list相应的命令进行rename,具体如下:
rename-command LPUSH OLD_LPUSH
rename-command RPOP OLD_RPOP
rename-command LLEN OLD_LLEN
rename-command RPOPLPUSH OLD_RPOPLPUSH
rename-command QPUSH LPUSH
rename-command QPOP RPOP
rename-command QLEN LLEN
rename-command QPOPRPUSH RPOPLPUSH
在redis-infq 项目文件夹下,redis-rename.conf配置文件已经完成上述配置,直接基于 这个配置启动即可。然后就可以通过list相关命令操作infQ。
infQ相关属性的配置,可以通过redis配置文件进行配置,具体配置示例如下:
######################## Configuration for InfQ ##############################
# Specify the log level of InfQ
infq-logging-level INFO
# Data path for InfQ.
# Make sure the directory exist, or creation of InfQ will fail.
infq-data-path ./infq_data_path/
# Memory block size of InfQ
# 1MB = 1048576
# 10MB = 10485760
# 20MB = 20971520
infq-mem-block-size 10485760
# Number of memory blocks for push queue
infq-pushq-blocks-num 30
# Number of memory blocks for pop queue
infq-popq-blocks-num 30
# 指定当push queue中已使用的block的百分比大于多少时,会触发dumper将内存块
# dump成文件块。
# 此值设置的过小,会导致不必要的磁盘IO;过大,可能会导致dumper来不及消费
# 造成push queue满。
infq-dump-blocks-usage 0.5
4. 运行
通过info命令,可以当前redis持有的infQ的信息,如下:
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=3,expires=0,avg_ttl=0
# InfQ
mem_block_size:10485760, pushq_blocks_num:30, popq_blocks_num:30
c=[publks:1, poblks:0, fblks:0, ms:629145744, fs:0, dumper: (0, 0), loader: (0, 0), unlinker: (0, 0)]
b=[publks:1, poblks:0, fblks:0, ms:629145744, fs:0, dumper: (0, 0), loader: (0, 0), unlinker: (0, 0)]
a=[publks:1, poblks:0, fblks:0, ms:629145744, fs:0, dumper: (0, 0), loader: (0, 0), unlinker: (0, 0)]
具体属性的含义如下:
mem_block_size: infQ的内存块尺寸
pushq_blocks_num: push queue包含的block数目上限
popq_blocks_num: pop queue包含的block数目上限
以上是所有infQ实例共用的属性,下面是单个infQ实例属性。
publks: 当前push queue包含的block数目
poblks: 当前pop queue包含的block数目
ms: 当前infQ实例占用的内存大小
fs: 当前infQ实例占用的文件大小
dumper、loader和unlinker:3个后台线程的状态。
5. 主从同步
对redis主从同步修改,支持了infQ的同步。在主从同步过程中,需要传输infQ的元数据、文件等,这块后续单独描述一下。