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 是压力测试工具

官方自带的性能测试工具

测试端口:

Redis(测试连接, 五大数据类型,三种特殊数据类型)_第1张图片

测试:

redis-benchmark -h localhost -p 6379 -c 100 -n 100000 先连接,之后在连接的基础上进行数据测试

Redis(测试连接, 五大数据类型,三种特殊数据类型)_第2张图片
Redis(测试连接, 五大数据类型,三种特殊数据类型)_第3张图片

基础知识

总共有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> 

Redis(测试连接, 五大数据类型,三种特殊数据类型)_第4张图片

数据库切换:

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

添加地理位置

有效精度范围:-180  180
有效维度范围:-85.05112878   85.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

你可能感兴趣的:(Linux,数据结构,redis,java,列表,linux)