Karl Seguin的一本小册子,很短,边读边实作,发现这把瑞士小军刀挺特别,哈哈。
戳这里 获取小册子的最新版。
引言
整本小册子主要介绍了五种数据结构String, Hash, List, Set, SortedSet 以其基本用法,一些更为高级的主题如Big O Notation, Transaction和一些重要的命令如expirt, sort,最后提到了有关配置configuration,验证authentication,备份backups,Redis集群cluster等等内容。
我们先安装,然后来看看五个主要的数据结构具体都是怎么玩的。
【以下均以Mac OSX上的操作为例】
安装
官方下载地址:https://redis.io/download
官方给到的安装命令:
wget http://download.redis.io/releases/redis-4.0.9.tar.gz
tar xzf redis-4.0.9.tar.gz
cd redis-4.0.9
make
如果你的Mac OSX裝了homebrew的话,直接:
brew install redis
装好后,根目录下执行 redis-server
, 就跑起来了。
开另一个窗口,执行redis-cli
, 进入redis的console, 可以通过info
命令来查看更多服务器相关信息。
好了,准备工作完成,来看看这五种数据结构。
Strings
基本用法:
set users:leto "{name: leto, planet: dune, likes: [spice]}"
get users:leto
strlen users:leto
getrange users:leto 1 9
append users:leto hello
get users:leto
incr stats:page:about
incrby rating:video:12333 5
简单说一下:
set <key> <value>
: 存储key-value
get <key>
: 获取key
strlen <key>
: 获取value的长度
getrange <key> <start> <end>
: 获取指定起始与终止位置的value子串
append <key> <new_value>
: 给key对应的value追加new_value
incr <key>
: value自动加1,没有设置value时,value默认是0
incrbr <key> <num>
: 给value加上num
Redis的所有命令可以查阅这里:https://redis.io/commands
此外,可以使用flushdb
清空所有数据。
Hashes
类似Strings的set,get, Hash中使用hset
, hget
, hmset
, hmget
.
基本用法:
hset users:goku powerlevel 900
hget users:goku powerlevel
hmset users:goku race cool age 20
hmget users:goku race powerlevel
hgetall users:goku
hkeys users:goku
hdel users:goku age
del users:goku
看输出其实就知道这些命令都是干嘛的,这里还是简单说一下:
【这里的field,指的就是hash中的key,为了便于区分,用field来代替。】
mset <key> <field1> <value1> <field2> <value2>...
: set多个field-value,value默认是string类型
mget <key> <field1> <field2>...
: get多个field对应的value
hgetall <key>
: 获取所有的field-value
hkeys <key>
: 获取所有的fields
hdel <key> <field>
: 删除某个field
del <key>
: 删除所有的fileds
第四章提到了keys Anti-Pattern, 给到的例子就是用Hashes来CRUD每个账户的bug信息。
Lists
基本用法:
rpush newusers goku
rpush newusers tom
ltrim newusers 0 10
lrange newusers 0 3
lrange newusers 2 10
简单说一下这些命令:
rpush <list> <item>
: push一个item到list, 例子中是在newusers的list中push了一个user goku
ltrim <list> <begin> <end>
: trim成指定的长度,例子中是到0~10
lrange <list> <begin> <end>
: 获取指定长度的list,上面的例子中,newusers这个list中有goku, tom,对应的index是0,1,所以lrange newuser 0 3
输出了goku, tom, 而lrange newuser 2 10
则为空。
书中提到了sets的一些场景,可用于存储logs或者跟踪用户浏览网站的足迹。
Sets
sets用来存储唯一值,同时提供一系列以集合为基础的运算,比如并集,交集。
一些基本用法:
sadd friends:leto paul tom jessica
sadd friends:duncan paul jessica alia
sismember friends:leto jessica
sismember friends:leto alia
sinter friends:leto friends:duncan
sinterstore friends:leto_duncan friends:leto friends:duncan
smembers friends:leto_duncan
简单说一下这些命令:
sadd <set> <member1> <member2> ....
: 给集合添加members
sismember <set> <member>
: 判断member是不是set中的元素, 1代表是,0代表不是。
sinter <set1> <set2>
: 求两个集合的交集
sinterstore <set1> <set2> <new_set>
:将两个集合的交集存储在一个新的集合new_set中
smembers <set>
: 查看set的members
Sorted Sets
Sorted Sets可以看成是带有score的sets。
基本用法:
zadd friends:leto 100 paul 90 tom 98 jessica 80 chani
zcount friends:leto 90 100
zrevrank friends:leto chani
zrank friends:leto chani
zrangebyscore friends:leto -inf +inf
简单说一下这些命令:
zadd <set> <score1> <member1> <score2> <member2>....
: 给set的members添加上score
zcount <set> <score_start> <score_end>
: set中score在score_start ~ score_end之间的member个数
zrevrank <set> <member>
: 降序排序后member的位置
zrank <set> <member>
:升序排序后member的位置【Redis的默认排序是升序】
zrangebyscore <set> -inf +inf
: 输出sorted set
sorted set的一个比较常用的场景是用来追踪以时间为纬度的事件。好吧,我没用过,这里就不举例子了。
其他一些好玩的命令
Expire
用来设置key的过期时间。
看个例子:
set pages:about 30 get pages:about expire pages:about 20 # 设置过期为20秒后 ttl pages:about # 查看还剩多少秒过期 persist pages:about # 取消过期设置 get pages:about expire pages:about 5 get pages:about # 此时pages:about过期,值变成了nil setex pages:detail 30 'More details' # set key= pages:about ,值为More details, 30秒后过期
Publication and subscriptions
可以订阅channel,取消channel,publish message,很cool!
玩一下。
在一个window上跑
redis-cli
, 执行subscribe warnings
, 另开一个window跑redis-cli
, 执行:publish warnings "hi,Redis~"
你会看到第一个window中的warnings channel接受到了信息“hi,Redis~”。
Monitor
好用的debugging 工具,可以清晰看到你的所有历史操作。
直接上图感受下:
Sort
sort可以用来给list,set, sorted set进行排序。
可以用limit来限定哪些records需要排序,用by指定排序依据。
看个例子感受下:
Something else
pipelining
Normally when a client sends a request to Redis it waits for the reply before sending the next request. With pipelining you can send a number of requests without waiting for their responses. This reduces the networking overhead and can result in significant performance gains.
正常情况下,当客户端发送请求给到redis时,它需要得到回复后才可能发送下一条请求。但是通过pipelining, 你可以在不需要等待回复的情况下,向Redis发送大量的请求。这减少了网络开支,显著提升了性能。
没用过,先记着。
Transaction
每个Redis的命令都是原子性的,当使用多个命令时,Redis同样支持transaction。
Redis is actually single-threaded, which is how every command is guaranteed to be atomic. While one command is executing, no other command will run.
Redis如何保证translation? 即原子性,一致性,隔离性,持久性?
- The commands will be executed in order
- The commands will be executed as a single atomic operation (without another client’s command being executed halfway through)
- That either all or none of the commands in the transaction will be executed
The end
读技术类书籍果然不比一般书籍,得跟着实作才有感觉,真想向天再借500年……