redis 5 命令大全
从网站迁移过来,格式有些问题
get
- 获取redis 键的值
- get key
- Laravel:
$result=Redis::get("key");
set
- 设置redis 键的值
- set key value
更多用法:
ex seconds 给设置的键顺便加上多少秒过期时间 和setex命令功能一样
例子:
127.0.0.1:6379> ttl java
(integer) 478
127.0.0.1:6379> set php 123 ex 100
OK
127.0.0.1:6379> ttl php
(integer) 97
px milliseconds 给设置的键顺便加上毫秒的过期时间
127.0.0.1:6379> set php 123 px 30000
OK
127.0.0.1:6379> ttl php
(integer) 27
nx: 键必须是不存在或者过期了才能设置成功(如何已经存在这个键,那就设置不成功)
127.0.0.1:6379> set php 123 ex 100
OK
127.0.0.1:6379> set php 123 ex 100 nx
(nil)
xx: 键必须是存在的情况下才能设置成功
127.0.0.1:6379> set php 123 ex 100
OK
127.0.0.1:6379> set php 444 ex 100 xx
OK
127.0.0.1:6379> get php
"444"
客户端使用:
PHP:Pedis
$result=Redis::set("java","php","ex","100","nx");
del
- 删除某个键
- del key
dbsize
- 获取redis键的总数
- dbsize
-
实现原理:并不是便利,而是直接获取内置的count
对于过期的键,也不会立刻就获取到准确的数据,
比如说 设置了1000个键 30秒后过期,
30秒钟之后dbsize 获取的数字只会慢慢减少, 所以也依赖 redis的定时删除机制,
而且设置键过期时间不要都设置成一样的时间,要随机的秒数,防止清除过期键的时候发生阻塞
- Laravel中使用
Redis::dbsize();
exists
- 检测这个键名为php的是否存在
- exists php
expireat
- 设置php这个键的过期时间为某个时间段的时间搓
- expireat php 1580113366
-
第二个参数必须是时间搓格式,如果小于当前日期那就直接过期了
客户端使用
PHP:pedis
$result=Redis::expireat("php",strtotime('2020-03-24 00:00:00'));
相似命令
ttl
- 查看php这个键还有多少秒过期
- ttl php
type
- 查看php这个键是什么类型
- type php
incr
- 自增键为php的值,默认自增1,第二个参数是自增的值
- incr php 或者 incr php 2
-
返回的都是自增完成之后的值
如果键不存在的话,自动+1 返回1
如果是incr的键的值是字符串的话会直接报错
相似命令
但是没有自减浮点数
客户端使用
PHP:pedis中使用
Redis::incr("post:1:total");
setex
- 设置php的值为fpm过期时间为60秒
- setex php 60 fpm
-
可以实现分布式锁
根据这个过期时间自动解锁
decr
- 设置php自减,默认自减1,第二个参数可设置自减值
- decr php 2
-
相似命令:
客户端使用:
$result=Redis::decr("php");
append
- 往键为java的值中追加字符串jvm
- append java jvm
-
如果追加了int类型的值那么就会自动转成string了
客户端使用
PHP:pedis
$result=Redis::append("php","sss");
会返回追加完之后字符串的长度
strlen
- strlen java统计键名为java的值的长度
- strlen java
-
客户端使用
PHP:pedis
Redis::set("php","我的天"); $result=Redis::strlen("php");
中文的话一个字的长度为3,所以会返回9
getset
- 设置java的值为jvm并且返回设置之前的值
- getset java jvm
-
客户端使用
PHP:pedis
$result=Redis::getset("php","我的天");
setrange
- 原来java的值是jvm,现在设置字符串下标1的值变为p,最后结果就是jpm
- setrange java 1 p
-
客户端使用
PHP:pedis
127.0.0.1:6379> set php abcd OK 127.0.0.1:6379> setrange php 2 g (integer) 4 127.0.0.1:6379> get php "abgd"
参数说明 setrange key offeset value
object encoding
- 先设置一个键num:key 值为123,然后查看编码格式会输出int
- set num:key 123
object encodibg num:key
hset
- 如果键不存在会自动创建,创建一个student 哈希表,并且设置键wl的值为123
-
hset key field value
hset student wl 123
-
如果键不存在则会自动创建,如果键已经存在则会覆盖
客户端使用
PHP:pedis
$result=Redis::hset("student","wl","123");
hget
- 获取哈西表student中键名为wl的值
- hget key field
hget student wl -
客户端使用
PHP:pedis
$result=Redis::hget("php:hash","wwww");
若想获取多个键 使用 hmget
hdel
- 删除哈西表student中键名为wl和xiaoming
- hdel student wl xiaoming
-
删除一个多个键
客户端使用
PHP:pedis
$result=Redis::del("php:hash","wl","wl1","wl2");
返回的值就是删除成功的个数
hlen
- 获取哈西表student中有多少个键
- hlen student
-
只能获取哈希表,获取其他类型会报错
客户端使用
PHP:pedis
$result=Redis::hlen("php:hash");
hmset
- 批量设置student哈希表的键和值
- hmset student wl 万隆 xiaoming 小明
hmget
- 批量获取student哈希表的某些键的值
- hmget student wl xiaoming
-
客户端使用
PHP:pedis
$result=Redis::hmget("php:hash","wl","xiaoming");
hexists
- 判断student哈希表中有没有wl这个键
- hexists student wl
-
客户端使用
PHP:pedis
$result=Redis::hexists("php:hash","wl");
如果存在则返回1
hkeys
- 获取student哈希表中所有的键
- hkeys student
-
客户端使用
PHP:pedis
$result=Redis::hkeys("student");
相似命令
hvals
- 获取student的所有值
- hvals student
-
不建议使用,可能值太多会导致阻塞
客户端使用
PHP:pedis
$result=Redis::hvals("php:hash");
相似命令
hgetall
- 获取student的所有的键和值,先输出键再输出值
- hgetall student
-
自己测试和小打小闹可以用这个命令,生产环境非常不建议用
hstrlen
- 获取student中wl值的长度
- hstrlen student wl
-
版本要求
>= Redis3.2
客户端使用
PHP:pedis
$result=Redis::hstrlen("student","wl");
rpush
- 往列表work的右边加入一条或多条记录
- rpush work 写bug
-
命令
rpush stu:list wl xiaoming xiaohong
客户端使用
$result=Redis::rpush("stu:list","wl","xiaoming","xiaohong");
会返回添加完之后的列表的个数
使用场景
laravel 框架中自带的队列工具就是使用的redis list, 可以把进行的操作push到list中,再使用 lpop 弹出来,如果要操作的内容过于复杂可以把要操作的内容存入Hash中,然后在List中只存键就可以了
相似命令
lrange
- 获取列表work的从左边开始数第0个到2的值
- lrange key startd end
- lrange work 0 2
-
获取所有值
lrange work 0 -1
客户端使用
PHP:Pedis
$result=Redis::lrange("stu:list","0","-1");
lpush
- 往列表work的左边插入一条记录,记录的值只能是string或者int
- lpush work 改bug
-
命令
lpush stu:list wl xiaoming xiaohong
客户端使用
$result=Redis::lpush("stu:list","wl","xiaoming","xiaohong");
会返回添加完之后的列表的个数
相似命令
lindex
- 获取列表work的第一条记录
- lindex work 0
-
客户端使用
PHP:pedis
$result=Redis::lindex("stu:list","1");
llen
- 获取列表work的长度
- llen work
-
客户端使用
PHP:pedis
$result=Redis::llen("stu:list");
lpop
- 获取列表work的左边的第一个值,并且删除
- lpop work
-
从左边开始按顺序弹出第一个元素,并且会删除掉
客户端使用
PHP:pedis
$result=Redis::lpop("stu:list");
会返回弹出的值
rpop
- 获取列表work的右边的第一个值,并且删除
- rpop work
-
从右边开始按顺序弹出第一个元素,并且会删除掉
客户端使用
PHP:pedis
$result=Redis::rpop("stu:list");
lset
- 修改列表中第0个元素的值为再写bug
- lset work 0 再写bug
-
前提是这个下标必须有值,不然修改一个不存在的下标的值会报错
ERR index out of range
客户端使用
PHP:pedis
$result=Redis::lset("stu:list",2,"写bug");
blpop
- 和lpop功能类似,只是如果列表为空的话就会一直阻塞,100是阻塞的秒数。当然这个阻塞不会影响其他命令的操作
- blpop work 100
-
具体介绍看 brpop 都差不多
brpop
- 和rpop功能类似,只是如果列表为空的话就会一直阻塞,200是阻塞的秒数。当然这个阻塞不会影响其他命令的操作
- brpop work 200
-
可以添加多个key 比如
bropo register_work email_work 200
越往前的列表如果先出现数据就会先弹前面的,这样就可以模拟任务优先级了
实际中:一个发送注册邮件的队列和日志迁移的队列,当有新的注册的时候就要优先执行发送邮件队列
客户端操作
PHP:pedis
$result=Redis::brpop("stu:list1",200); dd($result);
返回值
array:2 [ 0 => "stu:list1" 1 => "java" ]
如果列表中没有值的话,会一直等着,第二个参数就是等待的秒数 ,200秒后还没有值就会退出了,
PHP非cli的话要设置脚本最大运行时常
使用场景
模拟一个队列
PHP代码
while (true){ $result=Redis::brpop("stu:list1",200); if (!isset($result[1])){ continue; } if ($result[1]=="send_email"){ echo "收到发生邮件的任务"; }else{ echo $result[1]; } }
然后
lpush stu:list1 send_email
monitor
- 输出当前执行的所有命令
- monitor
hincrby
- 自增哈西表student 中wl列的值
- hincrby student wl
hincrbyfloat
- 自增哈西表student 中xiaoming列的值
- hincrbyfloat student xiaoming
linsert
- before是在列表studentlist中找wl,并将pipi插在它前面。而after是插在后头
- linsert studentlist before wl pipi
或者
linsert student after wl pipi -
在某个元素之前或者之后插入新的元素,当然会先查找,如果有相同的元素的话,就插入在排在左边的前面或者后面.
如果没找到要查询的元素会返回-1
客户端使用
PHP:pedis
$result=Redis::linsert("studentlist","after","wl","pipi");
$result=Redis::linsert("studentlist","before","wl","pipi");
sadd
- 往集合中添加元素,但是没有重复的数据,添加完成会返回一添加成功的集合个数,如果添加的值在其中则不算
- sadd resultSet java php
-
可以理解为是一个没有值的 哈希类型,只有键
客户端使用
$result=Redis::sadd("stu:set","java","php","net");
只会返回成功添加的个数,如果值已经存在了则不算
srem
- 把元素从集合中删除,会返回删除成功的个数
- srem resultSet java php
-
客户端使用
PHP:pedis
$result=Redis::srem("stu:set","java","php");
会返回删除成功的个数
scard
- 返回集合中列表的个数
- scard resultSet
-
客户端使用
PHP:pedis
$result=Redis::scard("stu:set");
sismember
- 判断java在不在集合中,如果在就返回1 不在为0
- sismember resultSet java
-
客户端使用
PHP:pedis
$result=Redis::sismember("stu:set","java");
srandmember
- 随机从集合中找两人,默认找一个人
- srandmember resultSet 2
-
随机找出几个元素 但是不会删除
客户端使用
PHP:pedis
$result=Redis::srandmember("stu:set","2");
spop
- 随机取出两个元素,默认只取出一个
- spop resultSet 2
-
随机拉两个元素出来,不记得看的是哪本书了,这个随机性不是太好
客户端使用
PHP:pedis
$result=Redis::spop("stu:set",2);
smembers
- 返回列表中所有的元素
- smembers resultSet
-
客户端使用
PHP:pedis
$result=Redis::smembers("stu:set");
DEBUG SEGFAULT
-
能够立刻让redis 崩溃,模拟断电
- DEBUG SEGFAULT
-
直接命令行使用吧
ping
-
发送一个测试,看看服务器是否还活着
- ping
-
echo
-
输出一些数据,和linux的echo 一个意思
- echo java
-
Laravel
dd(Redis::echo("java"));
object idletime java
-
查看java 这个键空闲了多久,就是既没有被查询也没有被修改
- object idletime
-
Laravel predis
dd(Redis::object("idletime","studeng"));
slowlog
- 用来记录查询执行时间的日志系统
- slowlog
-
主要用来记录慢查询,和查询超时的吊问题,记录下来的日志是存在内存中的,所以快,但是不持久啊(使用save是无法保存日志的),建议定时读取日志,存到本地
配置项: slowlog-log-slower-than 100 查询超过100微秒就记录,1秒=一百万微秒
建议设置为1毫秒也就是 1000微秒config get slowlog-log-slower-than
config get slowlog-max-len
查看已经记录了多少条日志
slowlog len
查看这些日志
slowlog get
127.0.0.1:6379> slowlog get 1) 1) (integer) 53 2) (integer) 1579424643 //什么时候时间 3) (integer) 147 //耗时(微秒 1秒=1000毫秒=1000 000 微秒) 4) 1) "GET" //命令 2) "aix_cache:aix_category" 5) "127.0.0.1:33084" //客户端 6) ""
清空日志
slowlog reset
客户端使用
PHP pedis
dd(Redis::slowlog("get"));
dd(Redis::slowlog("len"));
mset
- 设置多个键
- mset java 123 php 456
-
客户端使用
PHP:Pedis
$result=Redis::mset(["java"=>"22","php"=>"22222"]);
mget
- 获取多个键
- mset java php
-
只进行了一次网络请求
如果获取的键不存在的话,会返回一个空值 (nil) 不同的客户端会进行转换
客户端使用
PHP:Pedis
$result=Redis::mget(["java","php"]);
incrby
decrby
- 自减指定个数
- decrby php 3
-
如果键不存在会自动创建,最后会返回-3
已存在的键不可为字符串
客户端使用
PHP:pedis
$result=Redis::decrby("post:1:total","3");
incrbyfloat
getrange
- 获取部分字符串
- getrange php 0 2
-
客户端使用
PHP:pedis
$result=Redis::getrange("php","0","3");
参数说明
getrange key start end
lrem
- 删除list中的元素
- lrem stu:list 3 www
-
命令介绍
lrem key count value
count 是删除多少个元素,value 是删除名字为这些的元素(不支持模糊匹配)
如果有多个相同的元素
当count>0 的时候 从左往右删除,当count<0 从右往左删除 count==0 删除所有的
客户端使用
PHP:pedis
$result=Redis::lrem("stu:list","2","www");
ltrim
- 删除元素
- ltrim stu:list 1 3
-
除了下标1到3之间的元素,其他的全部删除
客户端使用
PHP:pedis
$result=Redis::ltrim("stu:list","1","3");
sinter
- 求出多个集合的交集
- sinter key [key...]
-
交集的意思就是 你有的我也有
使用场景
有多个兴趣爱好标签,这些标签中存储的都是用户id, 可以求出同时细化打篮球和打乒乓球的人,(但是只能是针对用户量小的情况下,多了就会出现bigkey了)
命令介绍
sinter key1 key2
客户端使用
PHP:pedis
$result=Redis::sinter("stu:set","stu:set1");
相似命令
sunion
- 求出多个集合的并集
- sunion stu:set1 stu:set2
-
并集就是你的和我的,合到一起,把重复的去除掉
客户端使用
PHP:pedis
$result=Redis::sunion("stu:set","stu:set1");
相似命令
sdiff
- 求出多个集合的差集
- sdiff key1 key2
-
差集就是你有的我没有,我没有的你有
客户端使用
PHP:pedis
$result=Redis::sdiff("stu:set","stu:set1");
🤘
相似命令
sinterstore
- 将多个集合的交集结果存在一个新的集合中
- sinterstore stu:set:save key1 key2
-
集合的运算非常耗时,所以存在一个新的集合中,然后如果老的集合变了在去计算一边, (弟中弟 缓中缓😎😂)
就是在原来计算交集的命令后加上store
如果新保存的这个键存在,redis会直接删除的,然后再写入
客户端使用
PHP:pedis
$result=Redis::sinterstore('stu:set:save',"stu:set","stu:set1");
sunionstore
- 将并集结果保存到新的集合中
- sunionstore stu:set:save key1 key2
-
集合的运算非常耗时,所以存在一个新的集合中,然后如果老的集合变了在去计算一边, (弟中弟 缓中缓😎😂)
就是在原来计算交集的命令后加上store
如果新保存的这个键存在,redis会直接删除的,然后再写入
客户端使用
PHP:pedis
$result=Redis::sunionstore('stu:set:save','stu:set','stu:set1');
sdiffstore
- 将差集结果保存到新的集合中
- sdiffstorestu:set:save key1 key2
-
集合的运算非常耗时,所以存在一个新的集合中,然后如果老的集合变了在去计算一边, (弟中弟 缓中缓😎😂)
就是在原来计算交集的命令后加上store
如果新保存的这个键存在,redis会直接删除的,然后再写入
客户端使用
PHP:pedis
$result=Redis::sdiffstore('stu:set:save','stu:set','stu:set1');
zadd
- 往有序集合中添加元素
- zadd stu:zset 100 ymh
-
添加的分数 score 是可以重复的,但是member是不可以重复的,如果member 存在的话 score 是会修改的,但是返回的结果就是0
redis3.2 新加了 nx,xx,ch ,incr 四个选项,和set 的几个选项的功能大差不差
nx : member必须不存在才能添加成功
zadd stu:zset NX 100 php
xx: member 必须存在才能添加成功
zadd stu:zset xx 200 php
ch : 返回此次操作后有序集合元素和分数发生变化的个数(member改变分数的也算)
zadd stu:zset ch xx 1 php
incr : 自增当前的分数,此时的12就是自增的分数了,返回的就是自增完成后的分数,如果member不存在也会自动创建的
zadd stu:zset ch xx incr 12 wl
命令介绍
zadd key score member
客户端使用
$result=Redis::zadd('stu:zset',"100","wl");
会返回添加成功之后的个数
zcard
- 计算有序集合中有多少个元素
- zcard stu:zset
-
客户端使用
PHP:pedis
$result=Redis::zcard('stu:zset');
zscore
- 计算有序集合中某个元素的分数
- zscore stu:zset wl
-
客户端使用
PHP:pedis
$result=Redis::zrevrank('stu:zset',"wl");
zrem
- 删除有序集合中的某个元素
- zrem key member
-
客户端使用
$result=Redis::zrem('stu:zset',"192");
zincrby
- 自增有序集合中的某个元素
- zincrby key 3 member
-
客户端使用
$result=Redis::zincrby('stu:zset',3,"wl");
返回的是自增完后的分数值
zrange
- 按照分数排序返回结果
- zincrby key start top withscore
-
按照分数从小到大排序返回
比如我想要前10个的结果 ,如果最后带上 withscore 会把分数值也一起返回给你
zincrby key 0 9
客户端使用
PHP:pedis中使用
$result=Redis::zrange('stu:zset',"0",'9');
pedis中无法使用 withscore参数
zrevrange
- 按照分数排序返回结果(倒叙)
- zrevrange key start top withscore
-
按照分数从大到小返回结果
比如我想要考试分数前10名的名单
如果说大家都考了100分怎办!!!!
redis 按照字典表给您排序好了
名字 第一个是数字考前,然后再是字母 1到9>a到z >A到Z 安排的妥妥当当的
客户端使用
PHP:pedis
$result=Redis::zrevrange('stu:zset',"0",'9');
相似命令
zrangebyscore
- 查询有序集合指定分数段的结果(带分页)
- zrangebyscore key 10 20 withscores limit 0 10
-
zrangebyscore 排序的结果是按照分数从小到大的
分页的参数跟mysql 的用法是一样的, limit (固定分页参数) 0 代表的从哪条开始 10 代码获取多少条记录
命令使用
zrangebyscore key min max [withscores] [limit offset count]
这个max 支持无限大 min支持无限小 举例 我想查询100以上的,但是不知道最高分多少分
zrangebyscore stu:zset 100 +inf withscores limit 0 10
查询一百分以下的zrangebyscore stu:zset -inf 100
默认是包含100分的,如果想不包含的话,在100前面加个小括号
zrangebyscore stu:zset -inf (100
客户端使用
PHP:pedis (手动分页)
$result=Redis::zrangebyscore('stu:zset',"-inf",'(100',"limit","0","10");
相似命令
!!!!
zrevrangebyscore
- 查询有序集合倒叙指定分数段的结果(带分页)
- zrevrangebyscore key max min [withscores] [limit offset count]
-
zrevrangebyscore 排序的结果是按照分数从大到小的
分页的参数跟mysql 的用法是一样的, limit (固定分页参数) 0 代表的从哪条开始 10 代码获取多少条记录
命令使用 (注意是先max 后mix)
zrevrangebyscore key max min [withscores] [limit offset count]
这个max 支持无限大 min支持无限小 举例 我想查询100以下的,但是不知道最低分多少分
zrevrangebyscore stu:zset 100 -inf withscores limit 0 10
查询一百分以上的
zrevrangebyscore stu:zset +inf 100
默认是包含100分的,如果想不包含的话,在100前面加个小括号
zrevrangebyscore stu:zset +inf (100
相似命令
zcount
- 返回指定分数范围的元素个数
- zcount key min max
-
也可以使用 ( 来加上不等于
直接统计所有元素
zcount stu:zset -inf +inf
客户端使用
PHP:pedis
$result=Redis::zcount('stu:zset',"80",'(100');
zremrangebyrank
- 有序集合按照排序删除元素 正序
- zremrangebyrank key start end
-
比如想把排名前4个元素给删除掉 (正序 分数从小到大)
zremrangebyrank stu:zset 0 3
客户端使用
$result=Redis::zremrangebyrank('stu:zset',"0",'4');
返回的是删除的个数
!!
zremrangebyscore
- 删除有序集合指定分数范围的元素
- zremrangebyscore key min max
-
比如想把排名前5分到10分的删除掉 当然也可以使用 ( 把5排除掉 和 +inf
zremrangebyscore stu:zset 5 10
客户端使用
$result=Redis::zremrangebyscore('stu:zset','5','10');
返回的是删除的个数
!!
zinterstore
- 获取两个有序集合的交集
- zinterstore save_key 2 stu:zset1 stu:zset2 1 aggregate max
-
获取两个有序集合的交集交集就是你有的我也有,然后会保存进一个新的有序集合命令使用 这个命令有5个参数
语法:ZINTERSTORE destination numkeys [WEIGHTS weight weight...] [AGGREGATE SUM | MIN | MAX]destination :代表计算结果保存的地方Numkeys: 代表你要计算几个集合的交集WEIGHTS :代表权重,它可以设置每个元素的权重,也就是在每个元素参与计算时,元素的分数会乘以你指定的一个权重。求两个集合中交集而且是取分数大的
ZINTERSTORE sut:save 2 stu:zset stu:zset1 weights 2 3 aggregate max
相似命令
zunionstore
- 求出两个有序集合的并集
- zunionstore save_key 2 stu:zset1 stu:zset2 1 aggregate max
-
获取两个有序集合的并集并集就是你有的和我有的,去掉重复的 然后会保存进一个新的有序集合命令使用 这个命令有5个参数
语法:zunionstore destination numkeys [WEIGHTS weight weight...] [AGGREGATE SUM | MIN | MAX]destination :代表计算结果保存的地方Numkeys: 代表你要计算几个集合的交集WEIGHTS :代表权重,它可以设置每个元素的权重,也就是在每个元素参与计算时,元素的分数会乘以你指定的一个权重。求两个集合中并集而且是取分数大的
zunionstore sut:save 2 stu:zset stu:zset1 weights 2 3 aggregate max
相似命令
rename
- 给键重命名
- rename key newkey
-
如果新的key 的名字已经存在的话会直接删除掉,然后写入
如果不想新的key 被强行删除的话使用 renamenx ,只有新key不存在才会写入
客户端使用
PHP:pedis
$result=Redis::rename('java1',"java2");
renamenx
- 给键重命名,新的键名必须不存在
- renamenxkey newkey
-
只有当新key 不存在的情况下才会重命名成功过
客户端使用
PHP:pedis
$result=Redis::renamenx('j',"php");
如果返回0 就是重命名失败
randomkey
- 随机返回一个键,不会删除
- randomkey
-
客户端使用
PHP:pedis
$result=Redis::RANDOMKEY();
expire
pexpire
pexpireat
persist
- 取消键的过期时间
- persist key
-
写个例子
127.0.0.1:6379> setex php2 100 123123 OK 127.0.0.1:6379> ttl php2 (integer) 97 127.0.0.1:6379> persist php2 (integer) 1 127.0.0.1:6379> ttl php2 (integer) -1 127.0.0.1:6379>
客户端使用
PHP:pedis
$result=Redis::persist("php");
scan
- 渐进式遍历redis的键
- scan cursor [match pattern] [count number]
-
首先做个测试往redis 中加个10万个键
用keys * 先遍历一下
100010) "java14705" 100011) "java81860" (5.72s)
直接5.7秒就一直卡着不动,因为单线程的原因,此时其他命令是无法执行的,都在等着keys执行完成
所以就需要用到我们的渐进式遍历了
命令使用
scan cursor [match pattern] [count number]
match 是加一些匹配条件 比如找 以user开头的键名 user* *的用法和mysql 是一样一样的
cursor 是一个游标,就是开始遍历的位置,刚开始的话就用0吧, 遍历完了就会返回给你下一次遍历的游标了,这就跟es 的深度分页是一样的
127.0.0.1:6379> scan 0 1) "57344" 2) 1) "java26498"
count 是你一次需要获取多少条
可能windows下的count 使用起来会出现不准的情况,count 20条返回了24条,linux下是OK的,
然后下一次就可以用 游标为 57344进行下一次遍历了
注意事项
但是scan 也并不是完美的,你在遍历了很多个游标的时候,这时候新增一个键可能就会遍历不到,所以这是开发过程中考虑的问题
当返回的游标为0 就意味着数据遍历完了 注意判断避免重复遍历了
相似命令
哈希表中渐进式遍历 hscan
集合中渐进式遍历 sscan
有序集合中渐进式遍历 zscan
客户端使用
PHP:pedis 遍历所有键
$keysArr=[]; $cursor=0; while (true) { $result=Redis::scan($cursor,"count","1000"); if (isset($result[0])) { $cursor=$result[0]; $keysArr=array_merge($keysArr,$result[1]); dump($cursor); } if (empty($cursor)) { dump("结束了".count($keysArr)); $redisKeyCount=Redis::dbsize(); dump($redisKeyCount); break; } }
keys
- 查看所有键
- keys aix:user:info:*
-
不建议在生产环境中使用,因为redis单线程的原因,执行这条命令的时候后面人全在排队等你执行完,而100万个键遍历2秒左右,
这个我们可以通过 slowlog 来查看日志3 代表的消耗的微秒 2087372微秒约等于2秒 这两秒内redis服务将会一直等待中
127.0.0.1:6379> slowlog get 1) 1) (integer) 184 2) (integer) 1580295728 3) (integer) 2087372 4) 1) "keys" 2) "*" 5) "172.19.0.1:42102" 6) ""
那么大家就全在等,然后所有应该请求缓存的全部打到数据库了,造成雪崩
建议使用 渐进式遍历
命令使用
匹配条件
* 代表匹配所有 (和mysql用法很像)
? 代表匹配一个字符串
[] 代表匹配部分字符串
举例子
我想找出所有以java 开头的键
127.0.0.1:6379> keys java*
找出键中包含java的
127.0.0.1:6379> keys *java*
[a,d] 代表匹配a 和b 两个结果 [a-d] 代表匹配a 到d的字符串 会 abcd 4中结果 而且区分大小写 , 1-9 同理
我想匹配 键名以 jav开头后一位必须是a和d的
127.0.0.1:6379> keys jav[a,d]*
后一位必须是大写的
127.0.0.1:6379> keys jav[A-Z]*
大小写不限制
127.0.0.1:6379> keys jav[a-z,A-Z]*
? 代表匹配一个字符串
比如我想匹配键名长度只有4位的而且还是j开头
127.0.0.1:6379> keys j???
客户端使用
PHP:pedis
$result=Redis::keys("java??");
redis-cli
- redis 自带客户端的使用
- redis-cli
-
查看客户端命令帮助
redis-cli --help
-a 代表着redis 的密码
redis-cli -a 123123
-r 代表的命令将会被执行多次 执行5次ping
redis-cli -a 123123 -r 5 ping
-i 表示多少秒执行一次命令 单位是秒 (每0.1秒执行一次ping 共5次)
redis-cli -a 123123 -r 5 -i 0.1 ping
例子: 每秒读取redis 使用的内存
redis-cli -a 123123 -r 100 -i 1 info | grep used_memory_human
-x 代表从标准输入读取,作为redis-cli 的最后一个参数 (此时java就作为最后一个参数了)
echo java| redis-cli -a 123123 -x set php
--bigkeys 查找redis中的bigkey 很强大
redis-cli -a Aa123123@ --bigkeys
结果翻译一遍就是
#扫描整个键空间以找到最大的键以及 #每个密钥类型的平均大小。你可以用-i 0.1睡眠0.1秒 #每100个扫描命令(通常不需要)。 [00.00%]到目前为止找到的最大字符串“javd762”,有3个字节 [00.00%]迄今为止发现的最大哈希值“jd”,有100000个字段 [42.66%]迄今为止找到的最大字符串“php”为5字节 --------摘要------- 在按键空间中取样143个按键! 以字节为单位的密钥总长度为960(平均长度为6.71) 找到的最大哈希“jd”有100000个字段 找到的最大字符串'php'有5个字节 包含0项的0个列表(键的00.00%,平均大小0.00) 具有100000个字段的1个哈希(密钥的00.70%,平均大小100000.00) 142个字符串,349字节(99.30%的键,平均大小2.46) 0个流和0个条目(键的00.00%,平均大小0.00) 包含0个成员的0个集(键的00.00%,平均大小0.00) 0个zsets,0个成员(密钥的00.00%,平均大小0.00)
--latency
用于检测网络延迟 其实和ping的结果差不多
redis-cli.exe -a 123123 -h sss.ssss.cn --latency min: 31, max: 388, avg: 35.94 (2579 samples)
最快31毫秒 平均35
--latency-history
这个就是每15秒输出一次结果
--latency-dist
以图表的形式输出........
--stat
能够实时打印redis server中stat的信息,挺好的
--raw
格式化输出的结果,比如结果中有中文的
redis-cli -a 123123 --raw get php
--no-raw
不格式化输出
!!!
redis-server
- redis 服务和测试
- redis-server
-
直接运行那就是启动redis-server服务
--test-memory 测试内存 将会测试分配1GB 内存来使用
redis-server --test-memory 1024
--help 看看帮助命令
redis-benchmark
- redis 的测试
- redis-benchmark
-
redis版本>=3.2 编译文件下会出现的 linux 环境按照官网安装应该在src目录下
主要用于测试 ,会对redis 种数据结构进行增删改查
-c 代表客户端并发的数量 默认是50
-n 代表客户端总请求量 默认10 0000
举个例子 一百个客户端,一共请求2w次
./redis-benchmark -c 100 -n 20000
====== GET ====== 20000 requests completed in 0.98 seconds
执行get请求 花了0.98秒 就相当于一个客户端执行了2000个
====== MSET (10 keys) ======
20000 requests completed in 1.25 seconds
2w个请求1.25秒完成了
-q 就是只显示 requests per second (redis 每秒钟处理多少个请求 )
./redis-benchmark -c 100 -n 20000 -q
-t 对指定的命令进行测试
./redis-benchmark -c 100 -n 20000 -t get,set -q
multi
- 开启事务
- multi
-
不支持回滚功能!!!!
127.0.0.1:6379> multi 开启事务 OK 127.0.0.1:6379> hset java one 123 执行命令 QUEUED 127.0.0.1:6379> hset java two 123 QUEUED 127.0.0.1:6379> hlen java QUEUED 127.0.0.1:6379> exec 提交事务 1) (integer) 1 2) (integer) 1 3) (integer) 3
开启了事务之后,这个客户端连接的命令都不会直接执行而且在exec后一起执行
但是其他客户端连接是不受影响的
放弃当前事务
discard
如果说在事务执行过程中其他客户端对其要执行的key 进行了修改
使用watch key 可以进行监控
127.0.0.1:6379> watch java 需要在执行事务之前进行watch OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> hset java three 123 QUEUED 127.0.0.1:6379> exec 在exec执行之前新客户端对watch的key进行修改,exec就会返回nill,上面执行的命令都不会生效 (nil) 127.0.0.1:6379>
新的客户端执行
127.0.0.1:6379> hset java four 123 (integer) 1
如果开启了事务之后执行的命令有语法错误, redis不会回滚,会把输入正确的命令执行掉,错误的命令只会报错
这需要开发人员自己注意!!!!
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> hset java 12 wqe QUEUED 127.0.0.1:6379> lpush java 123 QUEUED 127.0.0.1:6379> exec 第一条命令是正确的,第二条报错,但是不会影响到第一条 1) (integer) 1 2) (error) WRONGTYPE Operation against a key holding the wrong kind of value 127.0.0.1:6379> hget java 12 成功执行了 "wqe" 127.0.0.1:6379>
这只是个简单的事务,Lua 事务比它要强大
exec
- redis 事务操作
- exec
-
具体请看 redis事务
watch
- redis 事务操作,监听key
- watch
-
具体请看 redis事务
discard
- redis 事务操作,放弃事务
- discard
-
具体请看 redis事务
eval
- redis执行lua脚本
- eval
-
redis中lua脚本是原子性的,脚本执行的过程中其他命令是无法执行的
redis 版本需要大于2.6
命令介绍
eval script numkeys key [key....] arg [arg....]
script 就是要执行的lua脚本内容,需要引号或者双引号括起来
numkeys 就是你要传几个参数到脚本中,比如redis中lua无法使用随机数,那就写1传一个参数,默认必须要带0
key 就是参数1
arg 也是传入参数的😂
简单使用
eval "redis.call('set','lua','123')" 0
传参使用
eval "return redis.call('set','lua',KEYS[1])" 1 java
lua 数组的开始位置不是0 而是1
在redis的lua脚本中一些文件流,和系统的操作都无法使用了
lua脚本中提供操作redis的方法比如 redis.call()方法是可以执行redis的命令
redis.call('set','hello','123')
还有redis.pcall() 与call()最大的不同就是call执行redis命令如果报错了会立刻停下返回,但是pcall()不会停下继续执行下一条命令
eval "redis.call('set','lua','123') redis.pcall('hset','lua','ww','w') return redis.call('set','lua','qwe')" 0
如果说lua脚本比较耗时的话就会出现一些恶心的情况了
比如执行一个死循环的脚本
127.0.0.1:6379> eval "while 1==1 do print(123) end" 0
其他客户端再进行操作就会报错,就是过了redis 设置的超时时间
(error) BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
lua-time-limit 5000
其实完去没有必要增加超时时间,5000毫秒就是5秒啊,完去可以调成200毫秒
而且过了超时时间redis 也不会自动把你这个超时的脚本给停止掉,必须要开发人员自己杀掉脚本
SCRIPT KILL
这样redis 就恢复了
如果死循环脚本中的操作还是写的话(基本GG)
127.0.0.1:6379> eval "while 1==1 do redis.call('set','java','php') end" 0
此时只能执行(重启服务不保存数据)
SHUTDOWN NOSAVE
所以这风险大的不行,所以就需要自己把控了.管理好脚本的使用还是没有问题的,就像linux 有 rm -rf /* 咱还能不用了
相似命令
evalsha
- 执行存在的指定lua脚本
- evalsha
-
使用script load 先加载脚本到redis 内存中,然后才可使用evalsha
举例
127.0.0.1:6379> SCRIPT LOAD "return redis.call('set',KEYS[1],KEYS[2])" "00c8ea14c01a726d495f15046fa9d7c8dd778263" 127.0.0.1:6379> evalsha 00c8ea14c01a726d495f15046fa9d7c8dd778263 2 java net OK 127.0.0.1:6379> get java "net"
如果脚本不存在则会报错
(error) NOSCRIPT No matching script. Please use EVAL.
相似命令
script load
- 把lua脚本加载到redis内存中
- script load "redis.call('set','php','123')"
-
加载脚本到redis 内存中,方便使用evalsha命令调用
此脚本RDB方式并不会持久化,注意重启后脚本需要重新加载
但是开启AOF 持久化就还会存在
命令使用
script load "redis.call('set',KEYS[1],KEYS[2])"
不需要带numkeys参数
会返回给一串经过sha1加密的字符串
PHP实现计算内存sha1值的方法
$set_sh="return redis.call('set',KEYS[1],KEYS[2])"; $result=hash("sha1", $set_sh);
客户端使用
PHP:pedis
$set_sh="return redis.call('set',KEYS[1],KEYS[2])"; $result=Redis::script("load",$set_sh);
evalsha的使用
$set_sh="return redis.call('set',KEYS[1],KEYS[2])"; $lua_sha1=Redis::script("load",$set_sh); $result=Redis::evalsha($lua_sha1,2,"java","c++");
相似命令
script flush
- 清空所有的lua脚本
- script flush
-
清空所有的lua脚本
客户端使用
PHP:pedis
$lua_sha1=Redis::script("flush");
相似命令
script exists
- 判断脚本是否加载过
- script exists 00c8ea14c01a726d495f15046fa9d7c8dd778263
-
判断lua脚本是否加载过,方便evalsha直接调用
客户端使用
PHP:pedis
$set_sh="return redis.call('set',KEYS[1],KEYS[2])"; $sha1_exists=Redis::script("exists",hash("sha1", $set_sh),"qweqweq2e");
可以检测多个脚本是否存在,存在则返回1
相似命令
script kill
- 杀死正在运行的lua脚本
- script kill
-
杀死正在运行的lua脚本.一般用于脚本超时时候使用
详细使用见 redis中使用lua
相似命令
setbit
- 设置位图的
- setbit signin 32 1
-
原理小介绍
一个数字在64位机器上占8个字节,一个字节由64个二进制码构成
1MB=1024KB
1KB=1024B (字节)
所以位图存储一个亿的数据计算公式为
100000000/64*8/1024/1024 ≈ 11 MB
然后redis中位图只是用string存储的,
比 字母b 的 ASCll 码就是 98 (十进制),再把98转成二进制,但是转成二进制也没有64位啊,不足的话会进行补位,补成64位
二进制只有0和1,那么也就只能存储0和1默认的就是0
其实你可以把位图想象成只能存0和1 的超级大数字
这块想了解的更深可以去了解java中位图的实现
redis 会自动进行空间扩充并不会上来就占你一亿个空间,分配到10万的时候内存就会进行扩大了,切忌那种数据库的自增id上来就是几十万起步的,
也不要忘记设置过期时间
命令介绍
setbit key offset value
offset 只能是数字
value 只能是0和1
把第一位设成1 ,设置成功了之后会返回给你这个位之前的值
127.0.0.1:6379> setbit user:bit 1 1 (integer) 0 127.0.0.1:6379> getbit user:bit 1 (integer) 1 127.0.0.1:6379>
使用场景
可以记录用户的签到数据,用用户的唯一ID来记录,
注意事项:注意这个键不要被误删了..... 否则就是缓存判断没签到,实际签到数据进数据库又签到过了....
访客统计
但还是根据业务量吧,存数据量少都占空间,不如用 redis set类型存了
比如
127.0.0.1:6379> setbit big:bit:key 100000000 1 (integer) 0
设置偏移量为1亿的值为1,那么redis 就会自动分配一亿个坑,一亿大概就占了12MB内存
getbit
- 获取位图的偏移量
- getbit user:bit 20
-
主要是获取位图的偏移量
客户端使用
PHP:pedis
$result=Redis::getbit("user:bit",2);
bitcount
- 统计位图指定偏移量或者全部的值为1 的个数
- bitcount user:bit
-
看redis 源码中写的,实现原理感觉是遍历获取个数,没有存到某个变量中
命令介绍
bitcount key [start end]
start 和 end 不带就是查询全部
比如我想查看今天签到的人有多少个
127.0.0.1:6379> bitcount user:signin:2020-1-31 (integer) 20
用户id 1万之前的有多少个签到的
127.0.0.1:6379> bitcount user:signin:2020-1-31 0 10000 (integer) 0
客户端使用
PHP:pedis
$result=Redis::bitcount("user:bit",1,220000);
!!!
bitop
- 对多个位图进行操作
- bitop operaction destkey key [key ...]
-
operaction 参数值有 and(交集) or(并集) not(非) xor(异或)
destkey 是间的键名 操作的结果存在里头
先加测试数据把
for($i=1;$i<=100;$i++){ $result=Redis::setbit("user:sigin:2020:01:01",$i,1); $result=Redis::setbit("user:sigin:2020:01:02",$i+50,1); }
举个例子
查出今天和昨天都签到的人(应该是有50人都签到的) 就是取交集
127.0.0.1:6379> bitop and temp:sign user:sign:2020:01:01 user:sign:2020:01:02 (integer) 19 127.0.0.1:6379> bitcount temp:sign (integer) 50 127.0.0.1:6379>
然后再求并集, 两天内任意一天签到的人
127.0.0.1:6379> bitop or temp:sign user:sign:2020:01:01 user:sign:2020:01:02 (integer) 19 127.0.0.1:6379> bitcount temp:sign (integer) 150 127.0.0.1:6379>
XOR异或
就是把多个键挨个进行异或运算 , 相同的偏移量如果两个值一样则算出结果为0,值不一样算出结果则为1
bitop xor temp:sign user:sign:2020:01:01 user:sign:2020:01:02
最后算出结果是100,如果有第三个键一起运算的话,那么就是前两个运算出的结果和第三个算,然后再寸到 temp:sign中
Not 对一个键进行逻辑非运算
对这个位图的每一位进行 取反值 比如是0的旧变成1 比如是1的就变成0,但是如果我就第一个是1其他都是0 ,那岂不是.....
redis 是对你已经开辟的空间来进行取反的, 8个位为一组,比如我就 第0个设为1 那么一直到7 都会被取反,如果我第7个设置的是1那么前7个都会被取反
如果4的话这0到7都会被取反
bitpos
- 找出位图中第一个偏移量为0或者第一个偏移量为1的位置
- bitpos key bit [start] [end]
-
找出第一个值为1 的偏移量
127.0.0.1:6379> bitpos user:sign:2020:01:01 1 (integer) 1
找出第一个值为0 的偏移量
127.0.0.1:6379> bitpos user:sign:2020:01:01 0 (integer) 0
start 和 end 注意了, 参数是字节索引,也就是范围必须是8的倍数,等于输入的值乘8
127.0.0.1:6379> setbit java 1600 1 (integer) 0 127.0.0.1:6379> bitpos java 1 (integer) 1600 127.0.0.1:6379> bitpos java 1 0 200 (integer) 1600 127.0.0.1:6379> bitpos java 1 0 119 (integer) -1 127.0.0.1:6379>
pfadd
- 增加计数
- pfadd user:total
-
和set类型差不多
比如统计每天网站的UV,就是有多少个人访问的,不算重复的
可以使用set类型,但是只能用于小数据量,大了就太吃内存了,也可以使用bitmap来统计
HyperLogLog是占空间超小的用于统计的类型,但是有错误率,大概是0.8%
命令介绍
pfadd key element [element]
可以添加多个,但是就像set类型一样如果判断这个元素添加过了,就不会再添加进去了
使用场景
统计网站的UV, 当然如果业务量小还是选择占内存小的玩
客户端使用
PHP:pedis
for ($i=0; $i < 10000; $i++) { Redis::pfadd("user:total",uniqid()); }
pfcount
- 统计计数个数
- pfcount user:total
-
统计pfadd 添加的个数
命令介绍
pfcount key [key]
可以统计多个键的个数,最后会相加
客户端使用
PHP:pedis
$result=Redis::pfcount("user:total","java");
pfmerge
- 合并多个heyperLogLog的结果
- pfmerge destkey sourcekey [sourcekey]
-
合并多个,但是如何他们有相同的值,也会去重复的
不只是简单的3个相加
destkey 参数是把结果存到新的键中
新的这个结果key 也是heyperloglog 同样可以pfadd添加元素
客户端使用
$result=Redis::pfmerge("temp","user:total","user:total2");
geoadd
- 添加地理位置
- geoadd address 118.803185 31.97734 nanjing
-
redis3.2版本提供了geo(地理位置)功能,可以实现附近的人,以及计算两个坐标的距离
也不是上面新的数据类型,用的是zset实现的,所以zset的操作同样在这都生效的
获取城市坐标 百度坐标拾取
命令介绍
geoadd key longitude latitude member [longitude latitude member]
主要是添加坐标的功能
longitude 是经度
latitude 是纬度
member 是地区名称
比如往地址中添加一个南京
127.0.0.1:6379> geoadd address 118.803185 31.97734 nanjing
(integer) 1 127.0.0.1:6379>
修改坐标的话还是一样的命令但是返回的就是0
也可以添加多个,就继续往后面加就可以了
删除元素的话直接用zrem key member
因为它就是一个zset类型
客户端使用
$result=Redis::geoadd("address","119.430921","32.158828","zhengjiang");
geopos
- 获取地理位置的坐标
- geopos key member [member...]
-
获取南京和镇江的坐标(必须是添加过的)
127.0.0.1:6379> geopos address nanjing zhengjiang 1) 1) "118.80318313837051392" 2) "32.9773496264866921" 2) 1) "119.43092197179794312" 2) "32.15882733082832345" 127.0.0.1:6379>
客户端使用
$result=Redis::geopos("address","nanjing","zhengjiang");
geodist
- 获取两个地理位置的距离
- geodist key member member unit
-
获取两个点坐标之间的直线距离,不是行驶路径,行驶路径要调用百度地图接口了
命令介绍
geodist key member member2 [unit]
unit 表示的是返回结果的单位
m 表示米
km 表示千米
mi 表示英里
ft 表示尺
获取南京南到镇江南之间的距离
127.0.0.1:6379> geodist address nanjing zhengjiang km "108.4008" 127.0.0.1:6379>
客户端使用
$result=Redis::geodist("address","nanjing","zhengjiang","km");
georadius
- 获取指定地址范围内 地址的集合
- georadius key
-
主要是计算以某个中心点的地址, 有个相同功能的命令是georadiusbymember两个命令不同之处在于 georadius是输入经纬度而georadiusbymember 是直接输入存储地区的名字
命令介绍
georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] [ASC|DESC] [STORE key] [storedist key]
longitude 经度
radius 纬 度
radius 表示计算多少公里或者到大的距离
m|km|ft|mi 距离单位
withcoord 返回结果中包含经纬度
withdist 返回结果中包含离中心节点位置的距离
withhash 返回结果中包含geohash
Count 返回结果的个数
asc|desc 返回的结果按照距离中心的距离做升序或者降序
store key 将返回的结果保存到指定键
storedist key 将返回结果距离中心节点的距离保存到指定键
查看南京80KM 城市圈 按距离从小到大
georadius address 118.802422 32.090107 80 km asc
将距离的结果保存到新键
127.0.0.1:6379> georadius address 118.802422 32.090107 80 km asc storedist temp2 (integer) 4
查看数据
127.0.0.1:6379> zscan temp2 0 1) "0" 2) 1) "nanjing" 2) "0.30740197294342553" 3) "chuzhou" 4) "46.643752444182098" 5) "maanshan" 6) "49.398450199431977" 7) "zhengjiang" 8) "59.694090396331163"
滁州,马鞍山,镇江
不需要距离的结果存到新键,就用store temp1 两中存储可以一起使用
存到的都是一个zset 中
如果使用了store 和storedist 就不可以使用withcoord和withdist\withhash ,报错信息
(error) ERR STORE option in GEORADIUS is not compatible with WITHDIST, WITHHASH and WITHCOORDS options
使用场景
招聘网站,把所有职位的地址存到其中,然后就可以找到距离我最近的工作了,(但是往往这些数据都是存入es 引擎中)
georadiusbymember
- 获取指定地址范围内 地址的集合
- georadiusbymember
-
主要是计算以某个中心点的地址, 有个相同功能的命令是georadius两个命令不同之处在于 georadius是输入经纬度而georadiusbymember 是直接输入存储地区的名字
命令介绍
georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] [ASC|DESC] [STORE key] [storedist key]
longitude 经度
radius 纬 度
radius 表示计算多少公里或者到大的距离
m|km|ft|mi 距离单位
withcoord 返回结果中包含经纬度
withdist 返回结果中包含离中心节点位置的距离
withhash 返回结果中包含geohash
Count 返回结果的个数
asc|desc 返回的结果按照距离中心的距离做升序或者降序
store key 将返回的结果保存到指定键
storedist key 将返回结果距离中心节点的距离保存到指定键
查看南京80KM 城市圈 按距离从小到大
georadius address 118.802422 32.090107 80 km asc
将距离的结果保存到新键
127.0.0.1:6379> georadius address 118.802422 32.090107 80 km asc storedist temp2 (integer) 4
查看数据
127.0.0.1:6379> zscan temp2 0 1) "0" 2) 1) "nanjing" 2) "0.30740197294342553" 3) "chuzhou" 4) "46.643752444182098" 5) "maanshan" 6) "49.398450199431977" 7) "zhengjiang" 8) "59.694090396331163"
滁州,马鞍山,镇江
不需要距离的结果存到新键,就用store temp1 两中存储可以一起使用
存到的都是一个zset 中
如果使用了store 和storedist 就不可以使用withcoord和withdist\withhash ,报错信息
(error) ERR STORE option in GEORADIUS is not compatible with WITHDIST, WITHHASH and WITHCOORDS options
使用场景
招聘网站,把所有职位的地址存到其中,然后就可以找到距离我最近的工作了,(但是往往这些数据都是存入es 引擎中)
geohash
- 查看地址的geohash值
- geohash key member
-
redis 将经纬度转成一维数字
命令使用
127.0.0.1:6379> geohash address nanjing 1) "wtsqx65tg60"
字符串越长表示位置越准确,geohash长度为9的时候,精度在两米左右
两个字符串越来相似,他们之间的距离越月接近
publish
- 发布消息
- publish channel message
-
给订阅了这个频道的客户端发送一条消息,客户端和redis-server 是保持一个长的tcp连接
但是有很多的弱项,比如
消息无法持久化,
新的客户端无法收到旧的消息
命令介绍
publish channel message
channel 通道名称(不是key)
message 消息内容 string类型
会返回订阅这个频道的客户端数量
客户端使用
PHP:pedis
$result=Redis::publish("channel",uniqid());
subscribe
- 订阅某个或者多个频道
- subscribe channel [channel...]
-
订阅某个频道并且保持长连接接受发来的消息
127.0.0.1:6379> subscribe channel
此时 (往频道中发送一条消息,订阅的客户端就会收到消息了)
publish channel java2
但是如果此时又有一个客户端订阅了这个频道,java2这个消息是不会发给它的
客户端使用
PHP:pedis
$result=Redis::subscribe("channel",function($response){ dump($response); });
第二个参数是一个回调函数
使用场景
并没有想到什么好的使用场景,因为使用 list类型都可以实现
punsubscribe
- 模糊取消对某个或者多个频道的订阅
- punsubscribe [pattern]
-
取消成功后,将不会再接收该频道的消息
取消对 cha 开头的频道的订阅
127.0.0.1:6379> punsubscribe cha*
1) "punsubscribe"
2) "cha*"
3) (integer) 0客户端使用
PHP:pedis
Redis::unsubscribe("channel");
unsubscribe
- 取消某个频道或者多个频道的订阅
- unsubscribe [channel]
-
取消成功后,将不会再接收该频道的消息
取消对 channel 频道的订阅
127.0.0.1:6379> unsubscribe channel
客户端使用
PHP:pedis
Redis::unsubscribe(“channel”);
psubscribe
- 模糊订阅多个频道
- psubscribe [pattern]
-
订阅所有 cha开头的频道
psubscribe cha*
订阅所有的频道
psubscribe *
pubsub
- 查看频道的信息
- pubsub channels [pattern]
-
查看活跃的频道,至少有一个订阅的
127.0.0.1:6379> pubsub channels 1) "cha1"
以及模糊匹配
127.0.0.1:6379> pubsub channels cha* 1) "cha1"
查看频道订阅数
127.0.0.1:6379> pubsub numsub cha1 1) "cha1" 2) (integer) 1
查看模糊订阅的客户端数目
127.0.0.1:6379> pubsub numpat (integer) 1
必须使用 以下这种方式订阅的
psubscribe cha*
bitfield
- 对位图进行一系列的整数操作
- bitfield
-
Redis 版本>=3.2
bitfield 命令 允许用户在位图中的任意区域存储指定长度的整 数值, 并对 这些 整数 值 执行 加法 或 减法 操作。
支持 SET、 GET、 INCRBY、 OVERFLOW 这 4 个子 命令
与setbit不同的是setbit只能一位一位的设置,而bitfield 的set 可以连续设置多个位
SET
比如设置一个6
6的二进制是 110
127.0.0.1:6379> bitfield bitkey set u8 0 6 1) (integer) 0
u8 代表的是无符号的,8就是8位,比如这个6的二进制只有3位,就会进行补位, 补成
00000110
u代表无符号 i代表有符号
0是起始的偏移量
6是要设置的10进值的值
qweqw
- qweqwe
- qweqw
- qewqew