Redis基础

一、常识补充

点击进入redis官网

redis简介(Remote dictionary Server 远程字典服务器):

  • 是完全开源免费的,由C语言编写的,一个高性能的(key/value)分布式内存数据库,基于内存运行, 并支持持久化的Nosql数据库,也被称为" 数据结构服务器 "

提前剧透,redis关于key-value的三大特点:

  1. redis是支持持久化的! 我们可以控制 数据 何时,用何种方式 保存到磁盘中,每次重启再次加载该文件,可以完成数据恢复
  2. redis不单单支持简单的key-value数据类型,同时还可以提供list,set,hash,zset等数据类型的存储
  3. 支持数据的备份,mater-slave模式,即,当下时髦的主从复制读写分离

应用场景:

  • 内存存储的持久化: 虽然redis是单线程实现的,但是支持异步将数据持久化到硬盘上,同时不影响继续服务
  • 发布订阅
  • 定时器,计时器: 我们可以把这个特性用到发短信的服务中,每次发送完短信后,就进入倒计时,在指定的时间内,决绝发送第二次,有效的缓解短信服务的压力,节流
  • 取出最新的N个数据的操作: 比如新浪微博的评论系统,他要展示最新的10条评论,就是把最新的10条评论的id放到redis的list里面

二、安装

去官网下载压缩包:https://redis.io/download

安装依赖、编译、安装:

[root@instance-lynj0v9k-19 redis-5.0.9]# yum install gcc-c++
[root@instance-lynj0v9k-19 redis-5.0.9]# make
[root@instance-lynj0v9k-19 redis-5.0.9]# make install

安装成功后得到下图:

![image-20200918182406869](/Users/dxm/Library/Application Support/typora-user-images/image-20200918182406869.png)

我们自己安装的程序默认都在 /usr/local/bin目录下

![image-20200918182618458](/Users/dxm/Library/Application Support/typora-user-images/image-20200918182618458.png)

三、启动redis

将redis的配置文件拷贝到/usr/local/bin目录下, 之后使用这个配置文件启动

修改配置文件,让redis后台启动

daemonize no # 修改成 yes

指定配置文件,启动redis

![image-20200918183121073](/Users/dxm/Library/Application Support/typora-user-images/image-20200918183121073.png)

使用redis-client连接redis

![image-20200918183319018](/Users/dxm/Library/Application Support/typora-user-images/image-20200918183319018.png)

退出

# 关闭redis-server
127.0.0.1:16379> shutdown

# 退出redis-cli
not connected> exit

# 重新尝试连接,因为redis-server被关闭了,所以会被拒绝
[root@instance-lynj0v9k-19 bin]# redis-cli -p 16379
Could not connect to Redis at 127.0.0.1:16379: Connection refused
not connected> exit

# 查看redis-server是否还在
[root@instance-lynj0v9k-19 bin]# netstat -luntp | grep 16379
[root@instance-lynj0v9k-19 bin]#

四、常用基础命令

点击查看所有命令

# redis默认存在16个数据库,默认一开始使用的是第0个
[root@instance-lynj0v9k-19 bin]# cat redis.conf | grep  'databases'
databases 16

# 切换数据库
127.0.0.1:16379> select 2
OK
127.0.0.1:16379[2]>

# 查看数据库容量
127.0.0.1:16379[2]> DBSIZE
(integer) 0

# 查看所有的key
127.0.0.1:16379[2]> keys *
(empty list or set)

# 清空当前数据库中的值
127.0.0.1:16379[2]> flushdb
OK

# 清空所有库
127.0.0.1:16379[2]> flushall
OK
数据库的相关命令 指令
关闭redis shutdown
选择数据库 select 库索引
查看当前数据库中key的数量 Dbsize
清空当前库 Flushdb
通杀所有库 Flushall
key常用命令 指令
查看所有key keys *
判断某个key是否存在 exists key
把key移动到别的库 move key db
为key 设定过期时间 expire key 秒钟
查看还有多少秒过期 ttl key
查看当前key是什么类型的 type key

五、Redis五大基本数据类型

5.1、String

等同于java中的,Map<String,String>

  • string 是redis里面的最基本的数据类型,一个key对应一个value
  • string 是二进制安全的,意味着,就算我们通过加密算法把图片或者序列化的对象set给redis,它帮我们安全的存储
  • string的最大内存值 512M

常用命令:

常用命令 命令
添加一对kv set key value
添加多对kv(可覆盖) mset key value key value....
添加多对kv(不可覆盖,只要有一个已存在,全部取消) msetnx key value key value....
获取 get value
获取多对kv mget key key...
删除 del key
在末尾追加 append key value
查询v的长度 strlen key
给数值类型的v加/减1 incr/decr key
给数值类型增加/减少指定大小的值 incrby/decrby key value
获取v的长度 getrange key
在指定位置添加指定值(中间默认用空格补全) setrange key offset value
添加指定生命周期的kv setex key seconds value
如果不存在则添加 setnx key value
获取旧值,设置新值 setget key value

5.2、Hash

等同于java中的:Map<String,Map<String,String>>

  • redis的hash是一个键值对的集合 Map(string, Object)
  • redis的hash是一个string类型的field和value的映射表,特别适合存储对象

同样,hash相关的指令,以 h 开头

作用 命令
添加单个 hset key field value
获取单个 hget key field
一次性添加多个键值 hmset key field1 value1 field2 value2 ...
一次性获取多个 hmget
获取所有键值 hgetall key
删除 hdel
获取键值对的个数 hlen
检查是否包含某个字段 hget key field
查看所有key hkeys
给某个数值类型(否则报错)的值增加指定整数值 hincrby key field increment
给某个数字类型值,增加指定浮点类型值 hincrbyfloat key field increment
如果不存在则添加 hsetnx

5.3、List

等同于java中的Map<String,List<String>>

  • redis的list是一个简单的字符串类型的列表,从功能上看, 它就像是栈和队列结婚后的产物 首先: 它会按照我们插入的顺序排序, 然后我们可以从他的头部添加/获取元素,也可以从它的尾部添加/获取元素, (底层实际上是个链表)

list中有比较容易混淆的左右之分,我是把整个list看成一个两边相同的管子,如果是L开头的操作,就想象用左手把这个管子竖起来(我取名字叫左压栈),如果是R开头,就想象是右手把这个管子竖起来,这样就不会混淆取出来的值到底是谁

list相关的指令,开头全部是 l 意味list

常用命令 命令
左压栈 lpush key v1 v2 v3 v4...
右压栈 rpush key v1 v2 ...
查看里面的元素 lrange key start offset
左弹栈 lpop key
右弹栈 rpop key
按照索引查找 lindex key index
查看长度 llen key
删除几个几 lrem key 数量 value
指定开始和结束的位置截取,再赋值给key ltrim key start offset
右出栈左压栈,把resoure的左后一个,压倒dest的第一个 rpoplpush resource destination
重置指定索引的值 lset key index value
在指定元素前/后插入指定元素 linsert key before/after 值1 值2

性能总结:

他是一个字符串链表,left,right都可以插入添加

  • 如果键不存在,创建新的链表
  • 如果键已经存在,新增内容
  • 值全部移除,key消失
  • 由于是链表,所以它对头和尾操作的效率都极高,但是假如是对中间元素的操作,效率就可怜了

5.4、Set

等同于java中的Map<String,Set<String>>

  • 第一眼看到set,有没有想起来,它不允许有重复的元素? 没错,它的底层由hashTable实现的,天生去重

Set的所有指令,全部以 s 开头

常用命令 命令
添加值 sadd key values
查看值 smembers key
检查集合是否有值 sismember key value
查看set集合里面的元素个数 scard key
删除集合中的指定元素 srem key value
随机弹出某个元素 srandmember key
随机出栈 spop key
把key1中的某个值赋值给key2 smove SourceSet destSet member
数学集合类 命令
差集 sdiff
交集 sinte
并集 sunion

5.5、Zset

(sorted set: 有序集合)sort_set:可排序的set

  • 首先: 它同样具有set的特性,去重!
  • 其次: 每一个元素的value之前会关联上一个double类型的分数.redis会按照分数的成员,从小到大进行排序.(分数可以重复) 据说,我们平时玩的游戏得分排行榜就是它搞的

set的值是 k1 v1 k2 v2
zset的值 K1 score v1 k2 score v2

六、三大特殊数据类型

6.1、geospatial

官网地址:https://redis.io/commands/geoadd

可以用来推算两地之间的距离,方圆半径内的人

关于经度纬度的限制:https://www.redis.net.cn/order/3685.html

# 添加三个城市
127.0.0.1:16379[2]> geoadd china:city 116.40  39.99 beijing
(integer) 1
127.0.0.1:16379[2]> geoadd china:city 117.190 39.1255 tianjin
(integer) 1
127.0.0.1:16379[2]> geoadd china:city 120.36955 36.094 qingdao
(integer) 1
127.0.0.1:16379[2]>

# 获取指定key的经度和纬度
127.0.0.1:16379[2]> geopos china:city beijing
1) 1) "116.39999896287918091"
   2) "39.99000043587556519"
127.0.0.1:16379[2]>

# 获取两个给定位置的距离
127.0.0.1:16379[2]> geodist china:city beijing qingdao # 默认单位为米
"555465.2188"
127.0.0.1:16379[2]> geodist china:city beijing qingdao km
"555.4652"
127.0.0.1:16379[2]> geodist china:city beijing qingdao m
"555465.2188"
127.0.0.1:16379[2]> geodist china:city beijing qingdao mi # 英里
"345.1509"
127.0.0.1:16379[2]> geodist china:city beijing qingdao ft # 英尺
"1822392.4503"

# 查找附近的人
# 以给定的经纬度为中心,找出某一半径内的元素
127.0.0.1:16379[2]> georadius china:city 117.190 39.1255 200 km # 半径为200km
1) "tianjin"
2) "beijing"
127.0.0.1:16379[2]> georadius china:city 117.190 39.1255 200 km withdist # 指定显示距离
1) 1) "tianjin"
   2) "0.0001"
2) 1) "beijing"
   2) "117.6221"
127.0.0.1:16379[2]> georadius china:city 117.190 39.1255 200 km count 2 # 指定显示2个结果
1) 1) "tianjin"
   2) "0.0001"
2) 1) "beijing"
   2) "117.6221"

# 以指定的members为依据,找到它指定范围内的元素
127.0.0.1:16379[2]> GEORADIUSBYMEMBER china:city beijing 120 km
1) "beijing"
2) "tianjin"

# 返回一个或者多个位置的11位长度的hash串表示
127.0.0.1:16379[2]> geohash china:city beijing
1) "wx4g2xzyss0"
127.0.0.1:16379[2]> geohash china:city beijing tianjin
1) "wx4g2xzyss0"
2) "wwgqddx4sc0"

# geo底层使用 zset 实现
127.0.0.1:16379[2]> ZRANGE china:city 0 -1
1) "qingdao"
2) "tianjin"
3) "beijing"

# 可以通过zrem删除 geo添加的key中的member
127.0.0.1:16379[2]> ZREM china:city beijing
(integer) 1
127.0.0.1:16379[2]> ZRANGE china:city 0 -1
1) "qingdao"
2) "tianjin"

6.2、Hyperloglog

一般我们使用Hyperloglog做基数统计。

什么是基数?就是一个集合中不重复的数的个数

集合A:{1,3,5,7,9,7}

集合B:{1,3,5,7,9}

AB集合的基数都是5

应用:统计网站的访问量(一个人访问网站很多次仍然算作一次)

优点:占用的内存是固定的,找2^64次方个数的基数,只需要12KB内存

缺点:有0.81%的错误率,可以忽略不计

# PFCOUNT 计算出来的数量就是Set的基数
127.0.0.1:16379[2]> PFADD key4 q w e r q
(integer) 1
127.0.0.1:16379[2]> PFCOUNT key4
(integer) 4

# 添加key1和key对应的多个值
127.0.0.1:16379[2]> PFADD key1 q w e r
(integer) 1

# 统计key下有多少个值
127.0.0.1:16379[2]> PFCOUNT key1
(integer) 4

# 添加key2和key对应的多个值
127.0.0.1:16379[2]> PFADD key2 a s d f
(integer) 1

# 合并多个key成为一个key
127.0.0.1:16379[2]> PFMERGE key3 key1 key2
OK
127.0.0.1:16379[2]> PFCOUNT key3
(integer) 8

6.3、Bitmap

比如使用bitmap记录用户从1号到3号到登陆信息

# key为sign表示登陆
127.0.0.1:16379[2]> SETBIT sign 1 0 # 第一天没有登陆
(integer) 0
127.0.0.1:16379[2]> SETBIT sign 2 0
(integer) 0
127.0.0.1:16379[2]> SETBIT sign 3 1 # 第三天登陆了
(integer) 0

# 获取指定某位的值
127.0.0.1:16379[2]> GETBIT sign 3
(integer) 1

# 统计用户这三天登陆了几次,就是统计key下有多少位1
127.0.0.1:16379[2]> GETBIT sign 3
(integer) 1
127.0.0.1:16379[2]> bitcount sign
(integer) 1
posted @ 2019-07-08 13:00  赐我白日梦  阅读(636)  评论(0编辑  收藏  举报