民科技术速记
垃圾萌新,因为要用到一些东西所以现学,随手记录一下
内容可能有点勾史
Redis
Ref:https://zhuanlan.zhihu.com/p/469102289
Remote Dictionary Server / 远程字典服务,开源软件
基于内存的 key-value 的 NOSQL 数据库
首先想办法安装。以下假如安装目录是 /etc/redis
:
/etc/redis/bin
里是一些常用可执行文件
- redis 后台启动
redis-server [<configfile>]
其中 <configfile>
是一份配置文件。示例配置文件在 /etc/redis/redis.conf
,可以 cp
出来然后修改
查看 redis 是不是后台活着:
ps aux | grep redis
- redis 客户端
redis-cli [-h <host>] [-p <port>]
连接到某 redis 数据库。host 和 port 可以不填,默认 127.0.0.1:6379
- 关闭 redis 后台
法一:首先 ps
一下得到 redis 后台 pid,然后直接 kill <pid>
纱了。不优雅
法二:开客户端连接上,然后执行命令 shutdown
。或者直接 redis-cli [options] shutdown
也行
作为 key-value 数据库,redis 存储的所有 pair 的键名 key 都是字符串,而 value 支持的数据结构类型有很多种
数据类型有 string,hash,list,set,zset(有序集合)。同时每种数据结构的底层实现有不同种,称为「内部编码」,redis 会根据存储内容自己选择如何存数据
- 使用
object encoding <key>
来查询<key>
键对应的 value 的内部编码
以下简介常用命令
完整介绍可以在 redis-cli
里 help <command>
,或者去翻 redis 文档
全局命令
-
keys <pattern>
:Returns all key names that match a pattern.比如
keys *
返回所有键 -
dbsize
:返回键总数 -
exists <key> [<key>...]
:检查键是否存在 -
del <key> [<key>...]
:删除键 -
expire <key> <second>
:设置键<key>
在<second>
后过期 -
ttl <key>
:返回<key>
多长时间后过期如果一个键未被设置 ttl 那他就是无限期的,
ttl
返回 -1一个已死的键,或者是不存在的键(其实是一种东西),
ttl
返回 -2 -
type <key>
:返回<key>
所存的值的数据结构类型
string
set <key> <value> [<ex> seconds|<px> milliseconds] [nx|xx]
,设置 kv 对ex
:设置秒级过期时间px
:毫秒级过期时间nx
:键必须之前不存在才能设置成功。xx
:键必须存在才能设置成功。可单独用setnx
和setxx
替代
get <key>
获取值mset <key> <value> [<key> <value>...]
:批量设置值mget <key> [<key>...]
:批量获取值incr <key>
:将值为整数字符串的 +1- 值不是表示合法整数的字符串,返回错误
- 值是整数,返回自增后的结果
- 键不存在,创建键,默认初始为 0,在此之上自增 1
decr <key>
:自减,同上incrby <key> <increment>
:增加指定值decrby <key> <increment>
:减去指定值incrbyfloat <key> <increment>
:浮点
hash
hash 数据结构维护的是一个 hash table,里面存着一堆 kv 对,被称为 field-value
当一个哈希表里的所有 field 都被删干净了,其 key 和哈希表自动消失
-
hset <key> <field> <value> [<field> <value>...]
创建或者修改
<key>
指向的哈希表里的若干 field-value pair。返回新创建的 field 有多少个 -
hget <key> <field>
:返回<key>
指向的哈希表里<field>
的 value -
hdel <key> <field> [<field>...]
:删除 field -
hlen <key>
:返回一个哈希表里的 field 个数 -
hmset <key> <field> <value> [<field> <value>...]
:批量设置 field-value 对。hmset
和hset
似乎是效果相同的🤔:如果不存在 field 则创建,如果存在则修改其值 -
hmget <key> <field> [<field>...]
:获取一些 field 对应的 value -
hexists <key> <field>
:检查某 field 是否存在 -
hkeys <key>
:获取<key>
指向的哈希表的所有 field -
hvals <key>
:获取所有 value -
hgetall <key>
:获取所有的 field-value 对。返回的数组里按照一个 field 一个 value 这样顺序摆放 -
hincrby <key> <field> <increment>
:跟incrby
一样 -
hincrbyfloat <key> <field> <increment>
:浮点
这里有个比较生动的 hash 示例图:
lists
底层实现是个双向链表
和 hash 一样,如果链表里没元素了链表就会自己消失
-
lpush <key> <element> [<element>...]
:左 push 元素到链表,如果没有 key 就创建 -
rpush <key> <element> [<element>...]
:右 push -
linsert <key> (before|after) <pivot> <element>
:在 key 指向的链表里,找到最左出现的值为<pivot>
的元素,在其前/后插入新的元素<element>
可以把列表看成是一个双端队列,支持左右 push,下标由左到右递增,before 的意思是在靠下标更小的一侧插入
-
lrange <key> <start> <stop>
:返回一个 list 一个下标范围内的内容- 返回的是
[<start>, <stop>]
这个闭区间内的列表 - 列表的下标和 python list 同。具体来说:从左往右下标从 0 开始递增。而且从右至左,有另一种下标 -1,-2,...。
- 如果
<start>
的位置比<stop>
靠右,返回空而不报错
比如我们可以用
lrange <key> 0 -1
来取得所有元素 - 返回的是
-
lindex <key> <index>
:根据下标取得元素 -
llen <key>
:返回长度 -
lpop <key> [<count>]
:lpop 元素。如果不指定<count>
就 pop 一个 -
rpop <key> [<count>]
:rpop 元素 -
lrem <key> <count> <element>
:从列表中删除<count>
个<element>
- count > 0:从左到右,删除最多 count 个元素
- count < 0:从右到左,删除最多 abs(count) 个元素
- count = 0:删除所有
-
ltrim <key> <start> <end>
:修剪 list,使得只保留[<start>, <end>]
闭区间里的元素 -
lset <key> <index> <element>
:将<index>
处的元素修改为<element>
-
blpop <key> [<key>...] <timeout>
:在一个或多个 list 「阻塞左弹出」元素具体来说,redis 会逐个查看给出的 list,一旦发现当前考虑到的 list 非空,则左弹出一个元素返回。否则 redis 会开始阻塞,直到给出的 list 里有一个变为非空,或者到达 timeout 时间
-
brpop <key> [<key>...] <timeout>
:阻塞右弹出
利用 lpush + brpop 两个命令,可以使用 redis 实现类似消息队列的效果
set
set 维护无序的 element 集合。当最后一个 element 从 set 删除时,set 自动消失
sadd <key> <element> [<element>...]
:添加元素到 key 所指向的 set,如果 key 不存在则创建。返回新添加的元素个数,set 里已经有的元素不会重复被添加srem <key> <element> [<element>...]
:删除元素。返回被成功删除的元素个数,如果某元素未在 set 里出现则忽略smembers <key>
:获取一个 set 里的所有元素sismember <key> <element>
:检查一个元素是否在一个 set 里scard <key>
:返回一个集合的元素个数,复杂度 O(1)spop <key> [<count>]
:从一个集合里随机弹出 1 个或至多 count 个元素srandmember <key> [<count>]
:从一个集合里随机返回 1 个或至多 count 个元素sinter <key> [<key>...]
:返回多个集合的交集sunion <key> [<key>...]
:返回多个集合的并集sdiff <key> [<key>...]
:返回多个集合的差集
zset
所谓「有序集合」
保持着 set 的特性,比如集合内元素唯一,另一方面,它可以给每个元素赋予一个 score,表示指定这个 value 的排序权重。其底层用跳表实现
-
zadd <key> [nx|xx] [gt|lt] [ch] [incr] <score> <element> [<score> <element>...]
:向一个 zset 里添加元素,或者更新元素的 score,如果 key 不存在则创建score:“The score values should be the string representation of a double precision floating point number.
+inf
and-inf
values are valid values as well.”nx:元素必须不存在才可以成功执行。禁止插入新元素
xx:元素必须存在才可以成功执行。禁止更新已存在的元素
lt:当且仅当新的 score 小于现有的 score 时,一个已有元素才会被更新。不阻止新插入元素
gt:同上,新的 score 大于现有的 score 时更新 score
ch:“Modify the return value from the number of new elements added, to the total number of elements changed.” 这里的 changed element 指的是被新创建的元素,或者 score 发生变化的元素
incr:启用此选项将使得 zadd 的行为变为与
zincrby
相同,同时单次只允许指定一对<score> <element>
-
zcard <key>
:返回一个 zset 里的元素个数 -
zscore <key> <element>
:返回某元素的 score -
zrank <key> <element> [withscore]
:查询某元素的排名,按照 score 从低到高排序,score 最低的排名为 0。与之相对的命令zrevrank
则反之同时,如果两个元素的 score 一样,那么字典序小的在
zrank
命令下排名靠前 -
zrem <key> <element> [<element>...]
:删除元素 -
zincrby <key> <increment> <element>
:将某元素的 score 增加一个增量 -
zrange <key> <start> <end> [byscore|bylex] [rev] [limit <offset> <count>] [withscores]
:返回某一范围内的成员该命令相当于整合了
zrevrange
,zrangebyscore
,zrevrangebyscore
,zrangebylex
,zrevrangebylex
- 默认 zset 成员按照 score 第一关键字,字典序第二关键字从小到大排列,如果启用
rev
选项则反之 limit
选项用来取被选中区域的一个子集:跳过 offset 个元素,然后取出至多 count 个元素- 启用
withscores
选项,返回值里将附带上元素的 score - 如果没有启用
byscore
或者bylex
选项,<start>
和<end>
表示返回排名在[<start>, <end>]
闭区间里的所有元素 - 而关于
byscore|bylex
,表示按 score/字典序 排序,在一个范围内的元素,具体范围说明看文档 https://redis.io/commands/zrange/
- 默认 zset 成员按照 score 第一关键字,字典序第二关键字从小到大排列,如果启用
-
zcount <key> <min> <max>
:返回 score 处于一个范围里的元素个数。范围的具体定义与上面文档里 byscore 选项后的范围同 -
zrem <key> <element> [<element>...]
zremrangebylex <key> <min> <max>
zremrangebyrank <key> <start> <stop>
zremrangebyscore <key> <min> <max>
都是删除元素
-
zinterstore
和zunionstore
:取集合的交集、并集。内容见文档
slowlog
这个就不是数据结构类型了
slowlog 指慢查询日志。如果一个操作所使用的时间超过了阈值,就会将这次操作 log 一条。日志不是记在磁盘文件里的,而是在 redis 运行时记在内存里的一个表上
在配置文件中:
slowlog-log-slower-than
:设置阈值,单位是微秒,如果设置成小于 0 则不会 log 任何东西slowlog-max-len
:设置日志的最大长度,装不下了时候优先踢掉最早记录的一条
redis 跑起来之后在客户端用命令获取日志:
slowlog get [<count>]
:获取 1 条或至多 count 条日志slowlog len
:当前一共存了多少条日志slowlog reset
:清空所有日志记录
bitmap
一种特殊的数据结构类型。类比于 cpp 的 std::bitset
,可以理解为一种只存 01 的数组,更节省空间
-
setbit <key> <offset> <value>
:设置一个 bitmap 的 offset 位为 valueoffset 必须大于等于 0,小于 2^32(一个 bitmap 不会占用超过 512MB 内存)
如果 offset 符合要求,bitmap 会自己扩展到相应的长度以容纳该 bit,新被扩展的位初始值为 0
value 必须为 0 或 1 其中之一
-
getbit <key> <offset>
-
bitcount <key> [<start> <end> [byte|bit]]
:popcount,默认数全局的 1 的个数,也可以指定范围
bitmap 和 string 互通,string 可以被使用 bitmap 的操作,bitmap 也能当 string 被操作
未完待续。先发上来玩玩