前言:
现时同学们对“python操作hbase”都比较注重,朋友们都需要学习一些“python操作hbase”的相关资讯。那么小编同时在网络上收集了一些关于“python操作hbase””的相关资讯,希望兄弟们能喜欢,看官们一起来了解一下吧!Scrapy 框架本身没有分布式功能,但是配合 Redis 服务后就能实现分布式,于是就诞生了 Scrapy-Redis 这样的框架。它在 Scrapy 的基础上配合 Redis 进行了一些改造,实现了分布式的功能。本节会介绍 Redis 服务的相关操作,为后续使用和学习 Scrapy-Redis 打好基础。
1. Redis 介绍与安装
首先我们在 CentOS7.8 的系统上源码编译安装 redis-5.0 的最新版。按照下列步骤进行:
安装 gcc 等编译工具,下载 redis 5 的最新源码并解压:
[root@server2 shen]# wget 13:10:23-- download.redis.io (download.redis.io)... 109.74.203.151Connecting to download.redis.io (download.redis.io)|109.74.203.151|:80... connected.HTTP request sent, awaiting response... 200 OKLength: 1986574 (1.9M) [application/x-gzip]Saving to: ‘redis-5.0.9.tar.gz’100%[=========================================================================================================================================>] 1,986,574 12.9KB/s in 2m 11s 2020-06-27 13:12:35 (14.8 KB/s) - ‘redis-5.0.9.tar.gz’ saved [1986574/1986574][root@server2 shen]# tar xzf redis-5.0.9.tar.gz代码块123456789101112
进入 redis 源码目录,直接安装:
[root@server2 shen]# cd redis-5.0.9[root@server2 redis-5.0.9]# make MALLOC=libc PREFIX=/usr/local/redis install
添加 redis 命令路径:
[root@server2 redis-5.0.9]# cat /etc/profile...# 添加下面两行内容REDIS_HOME=/usr/local/redisexport PATH=$REDIS_HOME/bin:$PATH[root@server2 redis-5.0.9]# source /etc/profile[root@server2 redis-5.0.9]# which redis-cli/usr/local/redis/bin/redis-cli
添加并修改 redis.conf 配置文件:
[root@server2 redis-5.0.9]# mkdir /etc/redis[root@server2 redis-5.0.9]# cp redis.conf /etc/redis[root@server2 redis-5.0.9]# cat /etc/redis# ...# 修改第一处,改为后台守护进程方式启动daemonize yes# ...# 修改端口,比如改为6777port 6777# ...# 需要密码# requirepass foobaredrequirepass spyinx# ...# 允许通过公网访问该redis# bind 127.0.0.1bind 0.0.0.0
加入 systemd 服务,统一管理:
[root@server2 redis-5.0.9]# cat /etc/systemd/system/redis.service[Unit]Description=RedisAfter=network.target [Service]Type=forkingExecStart=/usr/local/redis/bin/redis-server /etc/redis/redis.confExecReload=/bin/kill -s HUP $MAINPIDExecStop=/usr/local/redis/bin/redis-cli -p 6777 shutdownPrivateTmp=true [Install]WantedBy=multi-user.target[root@server2 redis-5.0.9]# systemctl start redis[root@server2 redis-5.0.9]# systemctl status redis● redis.service - Redis Loaded: loaded (/etc/systemd/system/redis.service; disabled; vendor preset: disabled) Active: active (running) since Sat 2020-06-27 14:08:44 CST; 3s ago Process: 7080 ExecStart=/usr/local/redis/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS) Main PID: 7081 (redis-server) CGroup: /system.slice/redis.service └─7081 /usr/local/redis/bin/redis-server 0.0.0.0:6777Jun 27 14:08:44 server2 systemd[1]: Starting Redis...Jun 27 14:08:44 server2 redis-server[7080]: 7080:C 27 Jun 2020 14:08:44.938 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0OoJun 27 14:08:44 server2 redis-server[7080]: 7080:C 27 Jun 2020 14:08:44.938 # Redis version=5.0.9, bits=64, commit=00000000, ...startedJun 27 14:08:44 server2 redis-server[7080]: 7080:C 27 Jun 2020 14:08:44.938 # Configuration loadedJun 27 14:08:44 server2 systemd[1]: Started Redis.Hint: Some lines were ellipsized, use -l to show in full.# 设置开机启动[root@server2 redis-5.0.9]# systemctl enable redisCreated symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /etc/systemd/system/redis.service.代码块1234567891011121314151617181920212223242526272829303132333435
最后测试下 redis 服务是否能正常工作:
[root@server2 redis-5.0.9]# redis-cli -p 6777127.0.0.1:6777> auth spyinxOK127.0.0.1:6777> ping "hello, world""hello, world"127.0.0.1:6777> set hello worldOK127.0.0.1:6777> get hello"world"127.0.0.1:6777> 代码块12345678910
完成 redis 服务搭建后我们就可以开始 redis 服务的使用了。
2. Redis 的基本操作
我们会分成5个部分来介绍 redis 的基本数据类型,并进行实战演练。限于篇幅,这部分内容不会比较详细,许多重要的细节和知识点会被忽略。请重点参考 <<Redis使用手册>> 一书去深入学习和掌握 redis 的使用。
2.1 字符串
字符串是 Redis 最基本的键值对类型。它在数据库中将一个单独的键和单独的一个值关联起来。和 Python 字典类型中的 key-value 类似。常用的字符串操作命令有:
指令
含义
set
为字符串键设置值
get
获取字符串键的值
getset
获取旧值设置新值
mset
一次设置多个字符串键的值
mget
一次获取多个字符串键的值
msetnx
只在键不存在的情况下,一次为多个字符串键设置值
strlen
获取字符串值的字节长度
getrange
获取字符串值指定索引范围的值
setrange
对字符串值的指定索引范围进行设置
incrby/decrby
对指定值执行加法操作和减法操作
incrbyfloat
对整数值执行浮点数加法操作
接下来我们就使用上面的指令在 redis 的命令行中进行测试,请仔细查看每一步操作并动手实践:
首先是 set 和 get 指令,非常简单:
127.0.0.1:6777> set hello worldOK127.0.0.1:6777> get hello"world"127.0.0.1:6777>代码块12345
接着是 getset 指令,getset 返回的是旧值,同时会设置新的值
# 127.0.0.1:6777> getset hello "new world""world"127.0.0.1:6777> get hello"new world"127.0.0.1:6777>代码块123456
接着演示 mset 和 mget 指令,都是 set 和 get 的批量版,set 后面跟的是 key1 value1 key2 value2 … 这样的形式
# 127.0.0.1:6777> mset key1 value1 key2 value2 key3 value3OK127.0.0.1:6777> mget key1 key2 key31) "value1"2) "value2"3) "value3"127.0.0.1:6777>代码块12345678
msetnx 只能对不存在的键进行批量设置值,对于存在的键进行设置时会报错。返回0表示失败
# 127.0.0.1:6777> msetnx key3 value3 key4 value4(integer) 0127.0.0.1:6777> get key4(nil)代码块12345
类似于 python 中的 len(key1) 语句
# 127.0.0.1:6777> strlen key1(integer) 6代码块123
getrange 和 setrange 指令非常类似于 python 中的切片操作
# 127.0.0.1:6777> get key1"value1"127.0.0.1:6777> getrange key1 0 3"valu"127.0.0.1:6777> getrange key1 -3 -1"ue1"127.0.0.1:6777> setrange key1 2 xxx(integer) 6127.0.0.1:6777> get key1"vaxxx1"127.0.0.1:6777> setrange key1 10 ", this is so pretty!"(integer) 30代码块12345678910111213
可以看到,对于超出范围的,会用 \x00 填充
# 127.0.0.1:6777> get key1"vaxxx1\x00\x00\x00\x00, this is so pretty!"127.0.0.1:6777> 代码块1234
incrby、decrby 和 incrbyfloat 指令的实例
127.0.0.1:6777> set number 1OK127.0.0.1:6777> incrby number 100(integer) 101127.0.0.1:6777> get number"101"127.0.0.1:6777> decrby number 50(integer) 51127.0.0.1:6777> get number"51"代码块12345678910
加浮点数必须使用专门的指令,不能再使用 incrby 指令:
# 127.0.0.1:6777> incrby number 12.2(error) ERR value is not an integer or out of range127.0.0.1:6777> incrbyfloat number 12.2"63.2"代码块12345
redis 字符串类型的操作是不是比较简单?接下来还有更复杂的数据类型,请继续往下学习。
2.2 散列
Redis 的散列键会将一个键和一个散列在数据库中关联起来,用户可以在散列中对多个键设置值,这里会和前面字符串的操作一样。
散列结构显示
来看看 Redis 中用于操作散列数据类型的命令:
指令
含义
hset/hsetnx
为字段赋值/当键不存在时为字段赋值
hget
获取字段值
hincrby
对字段存储的整数值执行加法和减法动作
hincrbyfloat
对字段存储的数值执行浮点的加法和减法动作
hstrlen
获取字段值的字节长度
hexists
检查字段是否存在
hdel
删除字段
hlen
获取散列表中字段数
hmset
批量设置多个字段的值
hmget
批量获取多个字段的值
hkeys/hvals/hgetall
获取所有字段/所有值和所有字段和值
下面我们就来使用这些指令,进行实战演练。请仔细阅读下面的操作以及输出结果:
# hset/hsetnx/hget最基本的三个操作127.0.0.1:6777> hset books:1000 article 'life of article'(integer) 1# 返回0就是失败,1表示成功127.0.0.1:6777> hsetnx books:1000 article 'life of article'(integer) 0127.0.0.1:6777> hsetnx books:1000 history 'war of liberation'(integer) 1127.0.0.1:6777> hget books:1000 article"life of article"127.0.0.1:6777> hget books:1000 history"war of liberation"127.0.0.1:6777> 代码块12345678910111213
实战 hincrby 和 hincrbyfloat 指令:
# 127.0.0.1:6777> hset books:1000 number 100(integer) 1# 实现加法127.0.0.1:6777> hincrby books:1000 number 10(integer) 110# 实现减法127.0.0.1:6777> hincrby books:1000 number -10(integer) 100127.0.0.1:6777> hget books:1000 number"100"127.0.0.1:6777> hincrbyfloat books:1000 number -20.1"79.9"代码块12345678910111213
测试 hstrlen、hexists 和 hdel 指令:
# 127.0.0.1:6777> hget books:1000 article"life of article"127.0.0.1:6777> hstrlen books:1000 article(integer) 15127.0.0.1:6777> hget books:1000 number"79.9"# 返回1表示存在,0表示不存在127.0.0.1:6777> hexists books:1000 number(integer) 1# 删掉number字段127.0.0.1:6777> hdel books:1000 number(integer) 1127.0.0.1:6777> hexists books:1000 number(integer) 0代码块123456789101112131415
测试 hlen/hmset/hmget 命令:
# 127.0.0.1:6777> hlen books:1000(integer) 2127.0.0.1:6777> hmset books:1000 math "differential geometry" physics "quantum mechanics"OK127.0.0.1:6777> hlen books:1000(integer) 4127.0.0.1:6777> hmget books:1000 article history math physics1) "life of article"2) "war of liberation"3) "differential geometry"4) "quantum mechanics"代码块123456789101112
最后测试 hkeys/hvals/hgetall 指令:
# 127.0.0.1:6777> hkeys books:10001) "article"2) "history"3) "math"4) "physics"127.0.0.1:6777> hvals books:10001) "life of article"2) "war of liberation"3) "differential geometry"4) "quantum mechanics"127.0.0.1:6777> hgetall books:10001) "article"2) "life of article"3) "history"4) "war of liberation"5) "math"6) "differential geometry"7) "physics"8) "quantum mechanics"代码块1234567891011121314151617181920
看看上面的操作,是不是十分简单和明了?Redis 就是这么好用!
2.3 列表
Redis 中的列表和 Python 中的列表都是类似的。Redis 对于列表的数据类型也提供了很多操作指令,非常有意思。我们还是和上面一样,先给出部分常用的操作指令,然后逐个进行实战演示。来看看 Redis 中操作列表数据的指令:
指令
含义
lpush
将元素推入列表左端
rpush
将元素推入列表右端
lpushx/rpushx
只对已存在的列表执行推入操作
lpop
弹出最左端的元素
rpop
弹出列表最右端的元素
rpoplpush
将右边弹出的元素推入左边
llen
获取列表的长度
lindex
获取指定索引上的元素
lrange
获取指定索引范围的元素
lset
为指定索引设置新元素
linsert
将元素插入列表
ltrim
修建列表。接收一个列表和一个索引范围作为参数,并移除列表中位于给定索引范围之外的元素,只保留给定范围之内的元素
lrem
移除列表中指定元素
blpop
带有阻塞功能的左弹出操作
brpop
阻塞式右弹出操作
下面我们继续在我们的 redis 客户端命令行中进行操作,实践这些指令:
首先测试推入元素到列表的指令:lpush/rpush/lpushx/rpushx:
# 127.0.0.1:6777> lpush companies baidu alibaba tencent(integer) 3# lrange用于列表显示,先不用管它。看到一直左插入元素的结果如下127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"# 右边插入,需要把下面的列表横过来看127.0.0.1:6777> rpush companies bytedance(integer) 4127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"4) "bytedance"127.0.0.1:6777> lpushx companies chinatelecom (integer) 5127.0.0.1:6777> lrange companies 0 -11) "chinatelecom"2) "tencent"3) "alibaba"4) "baidu"5) "bytedance"#元素推进不存在的列表,失败,返回为0127.0.0.1:6777> lpushx not-exist chinatelecom (integer) 0代码块123456789101112131415161718192021222324252627
这里测试下列表元素的弹出功能,涉及的指令有 lpop/rpop/rpoplpush:
# 127.0.0.1:6777> lrange companies 0 -11) "chinatelecom"2) "tencent"3) "alibaba"4) "baidu"5) "bytedance"# 左端弹出操作,返回结果为弹出元素127.0.0.1:6777> lpop companies"chinatelecom"127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"4) "bytedance"# 右端弹出操作127.0.0.1:6777> rpop companies"bytedance"127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"# 右端弹出左端推入127.0.0.1:6777> lpush list1 a1 a2 a3(integer) 3127.0.0.1:6777> lpush list2 b1 b2 b3(integer) 3127.0.0.1:6777> lrange list1 0 -11) "a3"2) "a2"3) "a1"127.0.0.1:6777> lrange list2 0 -11) "b3"2) "b2"3) "b1"127.0.0.1:6777> rpoplpush list1 list2"a1"# 从list1的右端弹出,推入到list2的左端127.0.0.1:6777> lrange list1 0 -11) "a3"2) "a2"127.0.0.1:6777> lrange list2 0 -11) "a1"2) "b3"3) "b2"4) "b1"代码块12345678910111213141516171819202122232425262728293031323334353637383940414243444546
llen、lrange 和 lindex 指令:
# 127.0.0.1:6777> llen companies(integer) 3127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "baidu"127.0.0.1:6777> lrange companies 0 11) "tencent"2) "alibaba"# 超出列表索引范围,返回nil127.0.0.1:6777> lindex companies 3(nil)127.0.0.1:6777> lindex companies 2"baidu"127.0.0.1:6777> lindex companies 0"tencent"# 支持负数,倒着数127.0.0.1:6777> lindex companies -2"alibaba"代码块1234567891011121314151617181920
测试 lset/linsert/ltrim/lrem 指令:
# 127.0.0.1:6777> lset companies 2 meituanOK# 设置第三个元素为美团127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "meituan"127.0.0.1:6777> linsert companies after meituan xiaomi(integer) 4127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "meituan"4) "xiaomi"# 插入指令:insert list before|after 目标元素 插入元素127.0.0.1:6777> linsert companies before xiaomi jingdong(integer) 5127.0.0.1:6777> lrange companies 0 -11) "tencent"2) "alibaba"3) "meituan"4) "jingdong"5) "xiaomi"# 只保留1-3的值,其余全部去掉127.0.0.1:6777> ltrim companies 1 3OK127.0.0.1:6777> lrange companies 0 -11) "alibaba"2) "meituan"3) "jingdong"127.0.0.1:6777> lpush test_rem a a a b a c a a a(integer) 9# 0 表示的是删除所有a元素127.0.0.1:6777> lrem test_rem 0 a(integer) 7127.0.0.1:6777> lrange test_rem 0 -11) "c"2) "b"127.0.0.1:6777> rpop test_rem"b"127.0.0.1:6777> rpop test_rem"c"# 重新赋值127.0.0.1:6777> lpush test_rem a a a b a c a a a(integer) 9# 正数3表示从左向右,删除3个a127.0.0.1:6777> lrem test_rem 3 a(integer) 3127.0.0.1:6777> lrange test_rem 0 -11) "c"2) "a"3) "b"4) "a"5) "a"6) "a"# 负数3表示从右向左,删除3个a127.0.0.1:6777> lrem test_rem -3 a(integer) 3127.0.0.1:6777> lrange test_rem 0 -11) "c"2) "a"3) "b"代码块123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
这种命令行式的操作是不是非常简单?我们通过几次实验就能大致理解和掌握相关的指令含义。
2.4 集合
这个类型和 Python 的集合类型非常类似,Redis 也提供了丰富的指令对该类型的数据进行操作。首先来看常用的集合相关的指令:
指令
含义
sadd
将元素添加到集合
srem
从集合中移除元素
smove
将元素从一个集合移动到另一个集合中
smembers
获取集合包含的所有元素
scard
获取集合包含的元素数量
sismember
检查给定元素是否存在于集合中
srandmember
从集合中随机获取一个元素
spop
随机地从集合中移除指定数量的元素
sinter/sinterstore
对集合执行交集计算
sunion/sunionstore
对集合执行并集计算
sdiff/sdiffstore
对集合执行差集计算
下面继续开启 Redis 的实战,请仔细阅读下面的指令操作以及相关的结果输出,重要的地方我会做好注释。
sadd 指令添加集合数据:
# 127.0.0.1:6777> sadd databases 'mysql' 'oracle' 'redis' 'mongodb' 'xxxx'(integer) 5# srem指令移除xxxx元素127.0.0.1:6777> srem databases xxxx(integer) 1# smembers指令查看集合内的所有元素127.0.0.1:6777> smembers databases1) "mongodb"2) "redis"3) "mysql"4) "oracle"代码块123456789101112
smove 指令,将 databases 集合中的 redis 移动到 nosql 集合中:
127.0.0.1:6777> sadd nosql cassandra hbase(integer) 2# 127.0.0.1:6777> smove databases nosql redis(integer) 1127.0.0.1:6777> smembers databases1) "mysql"2) "mongodb"3) "oracle"127.0.0.1:6777> smembers nosql1) "cassandra"2) "hbase"3) "redis"代码块12345678910111213
scard 指令查看集合内元素个数:
# 127.0.0.1:6777> scard nosql(integer) 3# sismember判断元素是否在集合内,1表示在,0表示不在127.0.0.1:6777> sismember nosql redis(integer) 1127.0.0.1:6777> sismember databases redis(integer) 0代码块12345678
srandmember 指令返回集合内随机的元素,但是元素不会被移除:
# 127.0.0.1:6777> srandmember databases"oracle"127.0.0.1:6777> srandmember databases"mongodb"127.0.0.1:6777> srandmember databases"mysql"127.0.0.1:6777> srandmember databases"mysql"127.0.0.1:6777> smembers databases1) "mysql"2) "mongodb"3) "oracle"# 给集合databases添加两个元素127.0.0.1:6777> sadd databases 'test1' 'no'(integer) 2# 随机从databases集合中弹出一个元素127.0.0.1:6777> spop databases "mysql"# 随机从databases集合中弹出两个元素127.0.0.1:6777> spop databases 21) "test1"2) "mongodb"# spop指令会使得集合移除相应的弹出元素127.0.0.1:6777> smembers databases1) "no"2) "oracle"代码块123456789101112131415161718192021222324252627
计算集合的交并查:
# 127.0.0.1:6777> sadd test2 a1 a2 b1 b2 b3(integer) 5127.0.0.1:6777> sinter test1 test21) "a1"2) "a2"# sinterstore指令会将集合test1和test2的交集保存到集合store_inter中127.0.0.1:6777> sinterstore store_inter test1 test2(integer) 2127.0.0.1:6777> smembers store_inter 1) "a1"2) "a2"# sunion指令求两个集合的并集127.0.0.1:6777> sunion test1 test21) "b2"2) "b3"3) "b1"4) "a3"5) "a1"6) "a2"# sunionstore指令和sinterstore指令类似,将结果保存到另一个集合中127.0.0.1:6777> sunionstore store_union test1 test2(integer) 6127.0.0.1:6777> smembers store_union1) "b2"2) "b3"3) "b1"4) "a3"5) "a1"6) "a2"# sdiff指令表示的是集合test1有而集合test2中没有的元素127.0.0.1:6777> sdiff test1 test21) "a3"127.0.0.1:6777> sdiffstore store_diff test1 test2(integer) 1127.0.0.1:6777> smembers store_diff1) "a3"代码块12345678910111213141516171819202122232425262728293031323334353637
经过上面一系列实战之后,是不是对 Redis 有了初步的认识?Redis 的使用是不是非常简单?当然 Redis 服务提供的指令还有很多,涉及许多方面。接下来我们将会介绍 Redis 5中新增的一个重要的数据结构:流 (stream)。
2.5 流
流 (stream) 是Redis 5.0 中新增的数据结构,我们来看看 Redis 为该数据结构提供的相关指令:
指令
含义
xadd
追加新元素到流的末尾
xtrim
对流进行裁剪
xdel
移除指定元素
xlen
获取流包含的元素数量
xrange/xrevrange
访问流中元素
xread
以阻塞或非阻塞方式获取流元素
xgroup
创建消费者组
xreadgroup
读取消费者组
xack
确认消费消息
xpending
显示待处理消息的相关信息
xclaim
转移消息的归属权
xinfo
查看流和消费者组的相关信息
stream 指令的后半部分关于消费者组的,需要提前了解一些基本的消息队列知识才能上手实践。这里我简单实战下前半部分的指令,理解流的基本使用,和前面的列表非常类似。
xadd指令给一个流添加新元素,xrange可以查看流中的元素,这里指定流元素的 id=1000,流元素就是 {k1:value1,k2:value2}:
# 127.0.0.1:6777> xadd s1 100000 k1 value1 k2 value2"100000-0"127.0.0.1:6777> xrange s1 - +1) 1) "100000-0" 2) 1) "k1" 2) "value1" 3) "k2" 4) "value2"# 用*代替id,这样会根据当前时间戳自动生成一个id,{k3:value3}就是流元素127.0.0.1:6777> xadd s1 * k3 value3 "1593436935752-0"# 下一个插入的流元素id一定要大于流最后的元素id127.0.0.1:6777> xadd s1 1000 k4 value4 (error) ERR The ID specified in XADD is equal or smaller than the target stream top item127.0.0.1:6777> # 都这样了,就只好使用默认生成127.0.0.1:6777> xadd s1 * k4 value4 "1593437129285-0"# xrange指令用于显示指定范围的流元素,用id来作为范围。-表示最小的值,+表示最大的id值127.0.0.1:6777> xrange s1 - +1) 1) "100000-0" 2) 1) "k1" 2) "value1" 3) "k2" 4) "value2"2) 1) "1593436935752-0" 2) 1) "k3" 2) "value3"3) 1) "1593437129285-0" 2) 1) "k4" 2) "value4"# 使用count限制返回流元素的个数127.0.0.1:6777> xrange s1 - + count 21) 1) "100000-0" 2) 1) "k1" 2) "value1" 3) "k2" 4) "value2"2) 1) "1593436935752-0" 2) 1) "k3" 2) "value3"代码块12345678910111213141516171819202122232425262728293031323334353637383940414243
下面演示 xtrim/xdel/xlen 指令的使用:
# 127.0.0.1:6777> xlen s1(integer) 3# 为了测试方便,再添加两个流元素127.0.0.1:6777> xadd s1 * k5 value5 "1593437712761-0"127.0.0.1:6777> xadd s1 * k6 value6 "1593437717879-0"127.0.0.1:6777> xlen s1(integer) 5# 修改s1流,将元素裁剪到4个,这样就会删除最开头的元素127.0.0.1:6777> xtrim s1 maxlen 4(integer) 1127.0.0.1:6777> xrange s1 - +1) 1) "1593436935752-0" 2) 1) "k3" 2) "value3"2) 1) "1593437129285-0" 2) 1) "k4" 2) "value4"3) 1) "1593437712761-0" 2) 1) "k5" 2) "value5"4) 1) "1593437717879-0" 2) 1) "k6" 2) "value6"# 删除流id为1593437129285-0的元素127.0.0.1:6777> xdel s1 1593437129285-0(integer) 1127.0.0.1:6777> xrange s1 - +1) 1) "1593436935752-0" 2) 1) "k3" 2) "value3"2) 1) "1593437712761-0" 2) 1) "k5" 2) "value5"3) 1) "1593437717879-0" 2) 1) "k6" 2) "value6" # xread 指令从流 s1 中获取流 id>1593436935752-0 的元素,最多2个127.0.0.1:6777> xread count 2 streams s1 1593436935752-01) 1) "s1" 2) 1) 1) "1593437712761-0" 2) 1) "k5" 2) "value5" 2) 1) "1593437717879-0" 2) 1) "k6" 2) "value6"代码块12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
涉及更多的指令细节以及消费者组的指令使用,请参考 <<Redis使用手册>> 一书。
2.6 其他类型
限于篇幅,这里没有介绍到 Redis 的有序集合类型、位图和地理坐标等相关指令。读者可以自行参考文献2,里面详细介绍了 Redis 的大部分指令并对指令操作进行了绘图说明。
3. Python 实战 redis
Python 操作 redis 数据库也是非常简单的,我们有现成的第三方模块-redis,它实现了绝大部分官方命令并使用官方的语法和命令,使用起来和我们在命令行上操作 redis 数据库一致。首先来安装 Python 的 redis 模块:
[root@server2 ~]# pip3 install redisWARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.Collecting redis Downloading (72kB) 100% |████████████████████████████████| 81kB 17.0MB/s Installing collected packages: redisSuccessfully installed redis-3.5.3代码块1234567
接下来我们在 Python 的命令行中演示前面介绍的 Redis 中的字符串命令,请看完后认真实践下面的代码:
连接 redis 数据库,和 redis 服务在同一台机上:
# Python 3.6.8 (default, Apr 2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linuxType "help", "copyright", "credits" or "license" for more information.>>> import redis>>> r = redis.Redis(host='localhost', port=6777, password='spyinx', db=0)>>> r.set('hello', 'world')True>>> r.get('hello')b'world'代码块12345678910
实践 getset/mset/mget/strlen 指令:
# >>> r.getset('hello', 'new world')b'world'>>> r.get('hello')b'new world'>>> r.mset({'key1':'value1', 'key2':'value2', 'key3':'value3'})True>>> r.mget(['key1', 'key2', 'key3'])[b'value1', b'value2', b'value3']>>> r.strlen('key1')6代码块1234567891011
实践前面的 getrange/setrange 指令:
# >>> r.getrange("key1", 0, 3)b'valu'>>> r.getrange("key1", -3, -1)b'ue1'>>> r.setrange("key1", 2, 'xxx')6>>> r.get("key1")b'vaxxx1'代码块123456789
实践 incrby/decrby/incrbyfloat 指令:
# >>> r.set("number", 100)True>>> r.get("number")b'100'>>> r.incrby("number", 1)101>>> r.decrby("number", 50)51>>> r.get("number")b'51'>>> r.incrbyfloat("number", 22.1)73.1>>> r.incrbyfloat("number", -20.8)52.3
上面这些基础的 api 接口是不是和 redis-cli 命令行使用起来一模一样?所以,熟练掌握了 redis-cli 的指令用法,Python 操作 redis 也不在话下。
4. 小结
本小节我们主要介绍了 redis 相关的基础指令以及如何使用 Python 操作 redis,实现缓存数据的增删改查。这些是后续学习和使用分布式爬虫框架的基础,一定要牢牢掌握。
标签: #python操作hbase