Linux|Redis(测试连接, 五大数据类型,三种特殊数据类型)


文章目录

  • 测试性能
      • 测试端口:
      • 测试:
  • 基础知识
      • 总共有16个数据库,默认是0号数据库
      • 数据库切换:
      • 清空数据:
      • redis是单线程的
      • redis为什么是单线程还运行如此快?
  • 五大数据类型
      • Redis-Key
            • 基础命令:
      • String(字符串)
            • 字符串增减
            • 实现步长
            • 字符串范围,替换
            • setex,setnx
            • mset mget(遵从原子性,同时成功失败)
            • 对象
            • getset:先get后set
      • List 从左到右排列
            • 增加数据
            • 移除数据
            • 获取数据
            • 获取list长度
            • 移除指定的值
            • 截取指定区间的字符串
            • rpoplpush
            • lset
            • linsert
      • Set
      • Hash
            • key-Map
            • incr decr
      • Zset
            • 增删值,排序实现
            • 移除某个元素
            • 查询区间内的元素个数
  • 三种特殊数据类型
      • geospatial 地理位置
            • geoadd
            • geopos
            • geodist
            • georadius
            • georadiusbymember
            • geohash
            • zrm
      • hyperloglog
            • 测试使用
      • bitmaps
            • 统计打卡信息

测试性能 redis-benchmark 是压力测试工具
官方自带的性能测试工具
测试端口:
【Linux|Redis(测试连接, 五大数据类型,三种特殊数据类型)】Linux|Redis(测试连接, 五大数据类型,三种特殊数据类型)
文章图片

测试:
redis-benchmark -h localhost -p 6379 -c 100 -n 100000 先连接,之后在连接的基础上进行数据测试
Linux|Redis(测试连接, 五大数据类型,三种特殊数据类型)
文章图片

Linux|Redis(测试连接, 五大数据类型,三种特殊数据类型)
文章图片

基础知识 总共有16个数据库,默认是0号数据库
127.0.0.1:6379[3]> select 0 OK 127.0.0.1:6379> keys * 1) "name" 2) "myset" 3) "counter:__rand_int__" 4) "key:__rand_int__" 127.0.0.1:6379>

Linux|Redis(测试连接, 五大数据类型,三种特殊数据类型)
文章图片

数据库切换:
127.0.0.1:6379> select 3 #选择3号数据库 OK 127.0.0.1:6379[3]> dabasize (error) ERR unknown command `dabasize`, with args beginning with: 127.0.0.1:6379[3]> dbsize (integer) 0 127.0.0.1:6379[3]> set name yang OK 127.0.0.1:6379[3]> get key (nil) 127.0.0.1:6379[3]> get name "yang" 127.0.0.1:6379[3]> select 1#选择1号数据库 OK 127.0.0.1:6379[1]> get name (nil) 127.0.0.1:6379[1]>

清空数据:
  • flushdb #清除当前数据库
127.0.0.1:6379[1]> select 3 OK 127.0.0.1:6379[3]> keys * 1) "name" 127.0.0.1:6379[3]> flushdb #清除当前数据库 OK 127.0.0.1:6379[3]> keys * #获取所有数据 (empty list or set)

  • FLUSHALL 清空所有数据
127.0.0.1:6379> set name yang OK 127.0.0.1:6379> get name "yang" 127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> keys * (empty list or set) 127.0.0.1:6379[1]> FLUSHALL OK 127.0.0.1:6379[1]> select 0 OK 127.0.0.1:6379> keys * (empty list or set)

redis是单线程的
原因:redis是基于内存操作,CPU不是redis的性能瓶颈,redis的瓶颈是根据机器的内存和网络带宽,就使用单线程来实现了!
redis是c语言写的,运行速度完全不比key-value的Memecache差
redis为什么是单线程还运行如此快?
核心:redis是将所有的数据全部放在内存中的,所以说使用单线程来操作效率就是最高的,多线程的上下文切换是非常耗时的,对于内存系统来说,没有上下文切换就是效率最高的
五大数据类型 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库缓存消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
所有的命令都可以在官网中查看
Redis-Key
基础命令:
127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> keys * #查看所有的key (empty list or set) 127.0.0.1:6379> set name yang OK 127.0.0.1:6379> set age 1 OK 127.0.0.1:6379> keys * 1) "name" 2) "age" 127.0.0.1:6379> EXITS name #判断key是否存在 (error) ERR unknown command `EXITS`, with args beginning with: `name`, 127.0.0.1:6379> EXISTS name (integer) 1 127.0.0.1:6379> EXISTS name1 (integer) 0 127.0.0.1:6379> move name 1 #移除当前key (integer) 1 127.0.0.1:6379> keys * 1) "age" 127.0.0.1:6379> set name yang OK 127.0.0.1:6379> keys * 1) "name" 2) "age" 127.0.0.1:6379> get name "yang" 127.0.0.1:6379> EXPIRE name 10 #设置存在时间 (integer) 1 127.0.0.1:6379> ttl name (integer) 4 127.0.0.1:6379> ttl name#查看剩余存在时间 (integer) 1 127.0.0.1:6379> ttl name (integer) -2 127.0.0.1:6379> ttl name (integer) -2 127.0.0.1:6379> get name (nil) 127.0.0.1:6379> type age#查看数据类型 string

String(字符串)
字符串增减
127.0.0.1:6379> set key1 vi设置值 OK 127.0.0.1:6379> get key1获得值 "vi" 127.0.0.1:6379> keys *查看值 1) "key1" 127.0.0.1:6379> EXISTS key1 判断是否存在 (integer) 1 127.0.0.1:6379> APPEND key1 "ni"追加字符串,如果当前key不存在,就相当于创建key (integer) 4 127.0.0.1:6379> get key1 "vini" 127.0.0.1:6379> STRING key1获取字符串的长度 (error) ERR unknown command `STRING`, with args beginning with: `key1`, 127.0.0.1:6379> STRLEN key1 (integer) 4 127.0.0.1:6379> APPEND key1 "12123323243" (integer) 15 127.0.0.1:6379> get key1 "vini12123323243"

实现步长
实现步长i++ 127.0.0.1:6379> set views (error) ERR wrong number of arguments for 'set' command 127.0.0.1:6379> set views 0 OK 127.0.0.1:6379> incr views 自增1 (integer) 1 127.0.0.1:6379> incr views (integer) 2 127.0.0.1:6379> get views "2" 127.0.0.1:6379> decr views 自减1 (integer) 1 127.0.0.1:6379> decr views (integer) 0 127.0.0.1:6379> decr views (integer) -1 127.0.0.1:6379> incrby views 10设置步长,指定增减量 (integer) 9 127.0.0.1:6379> incrby views 10 (integer) 19 127.0.0.1:6379> decrby views 6 (integer) 13 127.0.0.1:6379> decrby views 6 (integer) 7 127.0.0.1:6379>

字符串范围,替换
127.0.0.1:6379> set key1 "i miss you , you forget me"设置值 OK 127.0.0.1:6379> get key1 "i miss you , you forget me" 127.0.0.1:6379> GETRANGE key (error) ERR wrong number of arguments for 'getrange' command 127.0.0.1:6379> GETRANGE key1 0 6获取指定区间的值(闭区间) "i miss " 127.0.0.1:6379> GETRANGE key1 0 -1“-1”代表获取所有值 "i miss you , you forget me" ================================================= 127.0.0.1:6379> set key2 scscsfsff OK 127.0.0.1:6379> get key2 "scscsfsff" 127.0.0.1:6379> SETRANGE key2 1 xx (integer) 9 127.0.0.1:6379> get key2 "sxxcsfsff" 127.0.0.1:6379> SETRANGE key2 1 hhhh替换指定位置开始的字符串为指定字符串 (integer) 9 127.0.0.1:6379> get key2 "shhhhfsff"

setex,setnx
127.0.0.1:6379> setex key3 30 "hhhhhsjdj" 设置key3的值,30秒后过期 OK 127.0.0.1:6379> ttl j=key3 (integer) -2 127.0.0.1:6379> ttl key3 (integer) 15 127.0.0.1:6379> keys * 1) "key3" 2) "key1" 3) "key2" 127.0.0.1:6379> ttl key3 (integer) -2 127.0.0.1:6379> setnx mykey "hello"如果不存在就创建一个新的 (integer) 1 127.0.0.1:6379> keys * 1) "mykey" 2) "key1" 3) "key2" 127.0.0.1:6379> setnx mykey "MongDB" 若果存在就会创建失败 (integer) 0 127.0.0.1:6379> get mykey "hello" 127.0.0.1:6379>

mset mget(遵从原子性,同时成功失败)
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 OK 127.0.0.1:6379> keys * 1) "k2" 2) "k3" 3) "k1" 127.0.0.1:6379> mget k1 k2 k3 1) "v1" 2) "v2" 3) "v3" 127.0.0.1:6379> msetnx k1 v1 k4 v4 (integer) 0 127.0.0.1:6379> get k4 (nil)

对象
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2 OK 127.0.0.1:6379> mget user:1:name user:1:age 1) "zhangsan" 2) "2"

getset:先get后set
127.0.0.1:6379> getset db redis (nil) 127.0.0.1:6379> get db "redis" 127.0.0.1:6379> getset db mongodb "redis" 127.0.0.1:6379> get db "mongodb"

使用场景 : 计数器 统计多单位的数量 对象缓存存储
List 从左到右排列
list是一种基本的数据类型
在redis里面,栈,队列,阻塞队列均可实现
所有的命令都是 l 开头的
增加数据
127.0.0.1:6379> LPUSH list one插入数据到列表的头部 (integer) 1 127.0.0.1:6379> lpush list two (integer) 2 127.0.0.1:6379> lpush list 3 (integer) 3 127.0.0.1:6379> lrange list 0 -1 获取列表中的值 1) "3" 2) "two" 3) "one" 127.0.0.1:6379> lrange list 0 1 获取列表中指定区间的值 1) "3" 2) "two" 127.0.0.1:6379> rpush list right (integer) 4 127.0.0.1:6379> lrange list 0 -1插入数据到列表的尾部 1) "3" 2) "two" 3) "one" 4) "right"

移除数据
127.0.0.1:6379> lrange list 0 -1 1) "3" 2) "two" 3) "one" 4) "right" 127.0.0.1:6379> lpop list 弹出左边的第一个数据 "3" 127.0.0.1:6379> rpop list 弹出右边的第一个数据 "right" 127.0.0.1:6379> lrange list 0 -1 1) "two" 2) "one"

获取数据 从左向右数
127.0.0.1:6379> lrange list 0 -1 通过下标获取值 1) "three" 2) "two" 3) "one" 127.0.0.1:6379> lindex list 2 "one"

获取list长度
127.0.0.1:6379> llen list (integer) 3

移除指定的值
127.0.0.1:6379> lrange list 0 -1 1) "four" 2) "three" 3) "two" 4) "one" 127.0.0.1:6379> lrem list 1 one 这里的数字指的是个数不是序数 (integer) 1 127.0.0.1:6379> lrange list 0 -1 1) "four" 2) "three" 3) "two"

截取指定区间的字符串
1) "hello" 2) "hello1" 3) "hello2" 127.0.0.1:6379> ltrim mulist 1 2 截取指定区间 OK 127.0.0.1:6379> lrange mulist 0 -1 1) "hello1" 2) "hello2"

rpoplpush 弹出原有列表右边的数据并存储到another列表中
127.0.0.1:6379> lrange mylist 0 -1 1) "hello" 2) "hello1" 3) "hello2" 127.0.0.1:6379> rpoplpush mylist another 弹出原有列表右边的数据并存储到another列表中 "hello2" 127.0.0.1:6379> lrange mylist 0 -1 1) "hello" 2) "hello1" 127.0.0.1:6379> lrange another 0 -1 1) "hello2" 127.0.0.1:6379> lpush mylist "hello3" (integer) 3 127.0.0.1:6379> lrange mylist 0 -1 1) "hello3" 2) "hello" 3) "hello1"

lset 不存在就报错,存在就更新
127.0.0.1:6379> lrange mylist 0 -1 1) "hello3" 2) "hello" 3) "hello1" 127.0.0.1:6379> lset myset 0 hhhh (error) ERR no such key 127.0.0.1:6379> lset mylist 0 hhhh OK 127.0.0.1:6379> lrange mylist 0 -1 1) "hhhh" 2) "hello" 3) "hello1"

linsert
127.0.0.1:6379> linsert mylist before "hello" "other" (integer) 4 127.0.0.1:6379> lrange mylist 0 -1 1) "other" 2) "hello" 3) "hello" 4) "hello" 127.0.0.1:6379> linsert mylist after "other" "miss" (integer) 5 127.0.0.1:6379> lrange mylist 0 -1 1) "other" 2) "miss" 3) "hello" 4) "hello" 5) "hello"

小结 实际是一个链表,before,after,left,right均可;
如果key不存在,创建新的链表
若果存在,进行更新
空链表也代表不存在
在两边掺入或改变值,效率最高
Set
Hash
key-Map 将key value中的value转换为map集合
127.0.0.1:6379> hset myhash field1 yang 设置一个具体键值 (integer) 1 127.0.0.1:6379> hget myhash field1 "yang" 127.0.0.1:6379> hmset myhash field1 miss field2 you设置多个具体键值 OK 127.0.0.1:6379> hmget myhash field1 field2 1) "miss" 2) "you" 127.0.0.1:6379> hgetall myhash 1) "field1" 2) "miss" 3) "field2" 4) "you" 127.0.0.1:6379> hdel myhash field1 删除某一个值 (integer) 1 127.0.0.1:6379> hgetall myhash 1) "field2" 2) "you" 127.0.0.1:6379> hlen myhash 计算长度 (integer) 2 127.0.0.1:6379> hexists myhash field1 判断是否存在指定的值 (integer) 1 127.0.0.1:6379> hkeys myhash 获取map中的key 1) "field2" 2) "field1" 127.0.0.1:6379> hvals myhash 获取map中的value 1) "you" 2) "miss"

incr decr
127.0.0.1:6379> hset myhash field3 5 (integer) 1 127.0.0.1:6379> hincrby myhash field3 3指定增量 (integer) 8 127.0.0.1:6379> hsetnx myhash field4 hello 如果不存在就创建 (integer) 1

hash存储变更的数据,更适合存储对象,string更适合存储字符串
Zset
增删值,排序实现
127.0.0.1:6379> zadd myset 1 one 添加用户 (integer) 1 127.0.0.1:6379> zadd myset 2 two 3 three (integer) 2 127.0.0.1:6379> zrange myset 0 -1 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> zadd salary 2500 xiaohong (integer) 1 127.0.0.1:6379> zadd salary 500 xiaohong2 (integer) 1 127.0.0.1:6379> zadd salary 10500 xiaohong3 (integer) 1 127.0.0.1:6379> zrangebyscore salary -inf +inf 升序排列 从小到大 1) "xiaohong2" 2) "xiaohong" 3) "xiaohong3" 127.0.0.1:6379> zrevrange salary 0 -1 降序排列,从大到小 1) "xiaohong3" 2) "xiaohong2" 127.0.0.1:6379> zrangebyscore salary -inf +inf withscores 1) "xiaohong2" 2) "500" 3) "xiaohong" 4) "2500" 5) "xiaohong3" 6) "10500"

移除某个元素
127.0.0.1:6379> zrange salary 0 -3 1) "xiaohong2" 127.0.0.1:6379> zrange salary 0 -1 1) "xiaohong2" 2) "xiaohong" 3) "xiaohong3" 127.0.0.1:6379> zrem salary xiaohong (integer) 1 127.0.0.1:6379> zrange salary 0 -1 1) "xiaohong2" 2) "xiaohong3" 127.0.0.1:6379> zcard salary 获取集合中的个数 (integer) 2

查询区间内的元素个数
127.0.0.1:6379> zadd myset 1 i 2 miss 3 you (integer) 3 127.0.0.1:6379> zrange myset 0 -1 1) "i" 2) "miss" 3) "you" 127.0.0.1:6379> zcount myset 1 2

三种特殊数据类型 geospatial 地理位置
定位,附近的人
先找一个在线查询城市地理位置的网站,查询经纬度
geoadd 添加地理位置
有效精度范围:-180180 有效维度范围:-85.0511287885.05112878 127.0.0.1:6379> geoadd china:city 116.40 39.30 beijing (integer) 1 127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai (integer) 1 127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing (integer) 1 127.0.0.1:6379> geoadd china:city 1114.05 22.52 shenzhen (error) ERR invalid longitude,latitude pair 1114.050000,22.520000 127.0.0.1:6379> geoadd china:city 114.05 22.52 shenzhen (integer) 1 127.0.0.1:6379> geoadd china:city 120.36 30.24 hangzhou 108.96 34.26 xian (integer) 2

geopos 获得当前定位,是坐标值
127.0.0.1:6379> geopos china:city beijing 1) 1) "116.39999896287918091" 2) "39.30000117660147652"

geodist 获取两地之间的距离,单位默认是 m
127.0.0.1:6379> GEODIST china:city beijing shanghai km "1008.3427" 127.0.0.1:6379> GEODIST china:city beijing shanghai "1008342.6601"

georadius 以半径找,注意空格的使用
127.0.0.1:6379> GEORADIUS china:city 100 30 1000 km精度 维度 范围 单位 1) "chongqing" 2) "xian" 127.0.0.1:6379> GEORADIUS china:city 100 30 2000 km withdist 1) 1) "chongqing" 2) "629.6756" 2) 1) "xian" 2) "967.2846" 3) 1) "shenzhen" 2) "1627.7179" 4) 1) "hangzhou" 2) "1956.3577" 5) 1) "beijing" 2) "1817.8853" 127.0.0.1:6379> GEORADIUS china:city 100 30 2000 km withcoord 1) 1) "chongqing" 2) 1) "106.49999767541885376" 2) "29.52999957900659211" 2) 1) "xian" 2) 1) "108.96000176668167114" 2) "34.25999964418929977" 3) 1) "shenzhen" 2) 1) "114.04999762773513794" 2) "22.5200000879503861" 4) 1) "hangzhou" 2) 1) "120.36000162363052368" 2) "30.2400003229490224" 5) 1) "beijing" 2) 1) "116.39999896287918091" 2) "39.30000117660147652" 127.0.0.1:6379> GEORADIUS china:city 100 30 2000 km withdist withcoord count 2 1) 1) "chongqing" 2) "629.6756" 3) 1) "106.49999767541885376" 2) "29.52999957900659211" 2) 1) "xian" 2) "967.2846" 3) 1) "108.96000176668167114" 2) "34.25999964418929977" 127.0.0.1:6379> GEORADIUS china:city 100 30 2000 km withdist withcoord count 3限制获得的数量 1) 1) "chongqing" 2) "629.6756" 3) 1) "106.49999767541885376" 2) "29.52999957900659211" 2) 1) "xian" 2) "967.2846" 3) 1) "108.96000176668167114" 2) "34.25999964418929977" 3) 1) "shenzhen" 2) "1627.7179" 3) 1) "114.04999762773513794" 2) "22.5200000879503861"

georadiusbymember
127.0.0.1:6379> GEORADIUSBYMEMBER china:city xian 2000 km 1) "chongqing" 2) "xian" 3) "shenzhen" 4) "hangzhou" 5) "shanghai" 6) "beijing"

geohash
将坐标转化为字符串 127.0.0.1:6379> geohash china:city beijing chongqing 1) "wwfz8drghe0" 2) "wm5xzrybty0"

zrm
127.0.0.1:6379> zrange china:city 0 -1 1) "chongqing" 2) "xian" 3) "shenzhen" 4) "hangzhou" 5) "shanghai" 6) "beijing" 127.0.0.1:6379> zrem china:city beijing 移除指定元素 (integer) 1 127.0.0.1:6379> zrange china:city 0 -1 1) "chongqing" 2) "xian" 3) "shenzhen" 4) "hangzhou" 5) "shanghai"

hyperloglog
基数:不重复的元素
redis hyperloglog基数统计的算法
优点:占用内存非常小,是固定的 12k
set 集合可用于统计人数,因为set集合元素不允许重复
测试使用
127.0.0.1:6379> PFadd mykey a b c d e f g h i j (integer) 1 127.0.0.1:6379> pfcount mykey (integer) 10 127.0.0.1:6379> pfadd mykey2 i j z x c v b n m (integer) 1 127.0.0.1:6379> pfcount mycount2 (integer) 0 127.0.0.1:6379> pfcount mykey2 (integer) 9 127.0.0.1:6379> PFMERGE mykey3 mykey mykey2合并两组元素 OK 127.0.0.1:6379> pfcount mykey3 (integer) 15

hyperloglog 会有一定的出错率
如果不允许容错,就使用set或者自己的数据类型即可
bitmaps
位存储:统计用户信息,打卡等 !两个状态的都可以使用bitmaps
bitmaps位图,都是操作二进制来进行记录,只有 0 和 1 两个状态
统计打卡信息
多用于统计信息 127.0.0.1:6379> setbit sign 0 1 (integer) 0 127.0.0.1:6379> setbit sign 1 0 (integer) 0 127.0.0.1:6379> setbit sign 2 0 (integer) 0 127.0.0.1:6379> setbit sign 3 1 (integer) 0 127.0.0.1:6379> setbit sign 4 0 (integer) 0 127.0.0.1:6379> getbit sign 3 查看某一天是否有打卡 (integer) 1 127.0.0.1:6379> getbit sign 2 (integer) 0 127.0.0.1:6379> bitcount sign统计打卡的天数 (integer) 2

    推荐阅读