redis-benchmark 是压力测试工具
官方自带的性能测试工具
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
先连接,之后在连接的基础上进行数据测试
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>
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是基于内存操作,CPU不是redis的性能瓶颈,redis的瓶颈是根据机器的内存和网络带宽,就使用单线程来实现了!
redis是c语言写的,运行速度完全不比key-value的Memecache差
核心: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)。
所有的命令都可以在官网中查看
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
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"
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>
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"
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是一种基本的数据类型
在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"
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"
弹出原有列表右边的数据并存储到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"
不存在就报错,存在就更新
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"
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不存在,创建新的链表
若果存在,进行更新
空链表也代表不存在
在两边掺入或改变值,效率最高
将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"
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更适合存储字符串
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
定位,附近的人
先找一个在线查询城市地理位置的网站,查询经纬度
添加地理位置
有效精度范围:-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
获得当前定位,是坐标值
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.39999896287918091"
2) "39.30000117660147652"
获取两地之间的距离,单位默认是 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"
以半径找,注意空格的使用
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"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city xian 2000 km
1) "chongqing"
2) "xian"
3) "shenzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"
将坐标转化为字符串
127.0.0.1:6379> geohash china:city beijing chongqing
1) "wwfz8drghe0"
2) "wm5xzrybty0"
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"
基数:不重复的元素
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位图,都是操作二进制来进行记录,只有 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