目录
数据库的分类
NoSQL
非结构化
认识 redis
特征
安装 redis
单机安装
Docker 安装
redis 的基本配置
启动 redis
关闭 redis
redis 开机自启
redis 客户端
redis 数据结构介绍
基本类型
String 的基础操作
List 基本操作
Set基本操作
Sorted Set基本操作
Hash基本操作
redis 通用命令
key 的层级格式
数据库的分类
-
关系型数据库
-
结构化数据
-
表中存储的数据格式是一样的
-
-
数据与数据之间是有关联关系的
-
-
非关系型数据库
-
每一条数据是完全独立的,不需要跟其他的数据之间建立关系
-
数据是非结构化的
-
非关系型数据库的分类:
-
文档型
-
mongdb
-
-
内存型
-
redis
-
数据都是以key-value形式存储数据的,支持数据持久化,它可以周期性的将数据刷到磁盘上(仅作备份使用)
-
是一个单进程应用,一个 redis 进程只能利用一个 cpu 核心
-
关系型数据库的缓存
-
session 等易失型数据的存储,会设置一个丢失的时间
-
消息队列
-
当 redis 充当消息队列时,不可以做高可用,只能部署 redis 单机
-
-
-
-
列式
-
hbase
-
oceanbase
-
-
图数据库
-
neo4j
-
NoSQL
sql | nosql | |
---|---|---|
数据结构 | 结构化(Structured) | 非结构化 |
数据关联 | 关联型 (Relational) | 无关联 |
查询方式 | Sql 查询 | 非 SQL |
事务特性 | ACID | BASE |
存储方式 | 磁盘 | 内存 |
扩展性 | 垂直 | 水平 |
使用场景 | 数据结构固定。相关业务对数据的一致性安全性有较高要求 | 数据结构不固定。对一致性,安全性要求不高,对性能有要求 |
非结构化
-
键值类型 (Redis)
-
文档类型 (MongoDB)
-
列类型 (HBase)
-
Graph 类型 (Neo4j)
认识 redis
Redis诞生于2009年全称是Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型NOSOL数据库
特征
-
键值型,value 支持多种不同数据结构,功能丰富
-
单线程,每个命令juyou原子性 (6版本网上都支持多线程了,但是只在网络请求的时候才能看见其效)
-
递延测,速度快(基于内存,IO多路复用,良好的编码)
-
支持数据的持久化
-
支持主从集群,分片集群
-
多语言客户端
安装 redis
单机安装
wget http://download.redis.io/releases/redis-7.0.10.tar.gz
tar xzf redis-7.0.10.tar.gz
cd redis-7.0.10/src
apt install -y make gcc pkg-config
make
make install
make test
# 启动 redis 它会占用当前会话,继续操作请开启新的会话
redis-server
Docker 安装
services:redis:image: bitnami/redis:latestrestart: alwayscontainer_name: redisenvironment:- REDIS_PASSWORD=123456ports:- '6379:6379'volumes:- redis-data:/bitnami/redis/data- redis-conf:/opt/bitnami/redis/mounted-etc- /etc/localtime:/etc/localtime:ro
volumes:redis-data:redis-conf:
redis 的基本配置
# 修改配置文件中的一个参数就可以达到在后台启动 redis
sed -i "s/daemonize no/daemonize yes/g" ~/redis-7.0.10/redis.conf
# 再次通过后台启动
redis-server ~/redis-7.0.10/redis.conf
# jobs 就行查看后台是否正常运行
# 查看端口是否正常
ss -tulnp | grep 6379
# 修改一些默认配置
# 1. 关闭保护模式
sed -i "s/protected-mode yes/protected-mode no/g" ~/redis-7.0.10/redis.conf
# 2. 密码设置, 默认时注释掉了的,我们解开注释,并且可以选择是否要更改密码
# 没有通过密码登录的用户,无法读/写 Redis。
1036 requirepass 123456
# 日志管理
logfile "/usr/local/redis/logs/redis.log"
# redis 在启动时,需要它开启多少个数据库
databases 16
# 数据备份 (持久化设置) 【rdb】
# 镜像备份文件的文件名
dbfilename 'dump.rdb'
# 数据库镜像备份的文件放置的路径。这里的路径跟文件名要分开配置是因为 Redis 在进行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成时,再把该临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放在这个指定的路径当中
dir /var/lib/redis
# 在进行镜像备份时,是否进行压缩
rdbcompression yes
# 900 秒有 1 条数句就备份
# 300 秒有 100 条数据就备份
# 60 秒有 10000 条数据就备份
save 900 1 300 100 60 10000
# 持久化【aof】
# AOF持久化。默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。所以 redis 提供了另外一种更加高效的数据库备份及灾难恢复方式。 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。但是这样做会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。所以推荐生产环境下的做法为关闭镜像,开启 appendonly.aof,同时可以选择在访问较少的时间每天对appendonly.aof 进行重写一次。
appendonly yes
# 指定AOF日志文件名
appendfilename appendonly.aof
# 设置对appendony.aof文件同步的频率,选项: always|everysec|no,默认值为everysec
appendfsync everysec
# 在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间,默认为no,表示"不暂缓",新的aof记录仍然会被立即同步
no-appendfsync-on-rewrite no
# aof每次rewrite之后,都会记住当前aof文件的大小,当文件增长到一定比例后,继续进行aof rewrite
auto-aof-rewrite-percentage 100
# 当aof文件最小达到64MB时,触发rewrite
auto-aof-rewrite-min-size 64mb
# 最大高并发数(同一时间最多支持多少客户机同时访问)
maxclients 10000
# 设置redis能够使用的最大内存。当内存满了的时候,如果还接收到set命令,则会按照max-memory-policy所指定的策略执行相应key删除操作
maxmemory 1Gi
# 如果redis使用的内存达到maxmemory设置的上限,则采用如下配置指定的策略进行相应操作,可配置如下策略:
# volatile-lru:默认策略,只对设置过期时间的key进行LRU算法删除。redis将先尝试剔除设置过expire信息的key,而不管该key的过期时间还没有到达。在删除时,将按照过期时间进行删除,最早将要被过期的key将最先被删除。如果带有expire信息的key都删光了,那么将返回错误。这样,redis将不再接收写请求,只接收get请求。
# allkeys-lru:删除不经常使用的key
# volatile-random:随机删除即将过期的key
# allkeys-random:随机删除一个key
# volatile-ttl:删除即将过期的key
# noevictiom:不过期,写操作返回报错
maxmemory-policy volatile-lru
# 开启远程访问 <绑定监听的 ip 地址>
bind <ip_addr>
# 日志级别分为4级,debug verbose notice warning
loglevel notice
# 启动和关闭 redis
# cat /etc/systemd/system/redis-server.service
启动 redis
# 进入 redis 的安装路径
# 启动
redis-server redis.conf
关闭 redis
kill -9 <redis 的进程id>
redis 开机自启
vim /etc/systemd/system/redis.service[Unit]
Description=redis-server
After=network.target[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf[Install]
WantedBy=multi-user.target# 重新加载服务
systemctl daemon-reload
systemctl start redis
systemctl restart redis
systemctl stop redis
systemctl enable redis
systemctl disable redis
systemctl status redis
redis 客户端
redis 安装完成后就自带了命令行客户端, redis-cli 使用如下方式
redis-cli [option] [commonds]
其中常见的 option 选项
-
-h 127.0.0.1 : 指定要连接的 redis 节点的 IP 地址,默认是 127.0.0.1
-
-p 6379 指定要连接的 redis 节点的端口,默认是 6379
-
-a 123456 指定 redis 的访问密码 (还有一种方式就是进入 redis-cli 交互式界面之后通过 AUTH <密码> )
其中常见的 commonds 就是 Redis 的操作命令,例如
ping 与 redis 服务器做心跳测试,服务器会正常返回 pong ,不指定 commond 时,会进入 redis-cli 的交互平台
redis 数据结构介绍
redis 是一个 key-value 的数据库, key 一般是 String 类型,不过 value 的类型多种多样
String,Hash,List,Set,SortedSet,GEO,BitMap,HyperLog
前五个是基本类型,后面三个是在基本类型的基础之上做了一些特殊的功能,所以也被称之为特殊类型
基本类型
String 的基础操作
String 类型,也就是字符型,是 Redis 中最简单的存储类型,其 value 是字符串,不过根据字符串的格式不同,又可以分为 3 类:
-
String 普通字符串
-
int 整数类型,可以做自增,自减操作
-
float 浮点型,可以做自增,自减操作
不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型最大空间不能超过 512m
SET # 添加或修改已经存在的一个 String 类型的键值对
GET # 根据 key 获取 String 类型的 value
MSET # 批量添加多个 String 类型的键值对
MGET # 根据多个 key 获取多个 string 类型的 value
INCR # 让一个整型的 key 自增 1
INCRBY # 让一个整型的 key 自增并指定步长,例如让 num 每次自增 2 (使用负数可以让其自减)
INCRBYFLOAT # 让一个浮点型的 key 自增长并且指定步长
SETNX # 添加一个 string 类型的键值对,前提是这个 key 不存在
SETEX # 添加一个 string 类型的键值对,并且指定有效期
# string 的基础操作
# 设置key对应的值为string类型的value,返回1表示成功,0失败
set key value
# 同上,如果key已经存在,返回0 。nx 是not exist的意思
setnx key value
# 获取key对应的string值,如果key不存在返回nil
get key
# 一次获取多个key的值,如果对应key不存在,则对应返回nil
mget key1 key2 ... keyN
# 一次设置多个key的值,成功返回1表示所有的值都设置了,失败返回0表示没有任何值被设置
mset key1 value1 ... keyN valueN
# 同上,但是不会覆盖已经存在的key
msetnx key1 value1 ... keyN valueN
# 对key的值做加加操作,并返回新的值。注意incr一个不是int的value会返回错误,incr一个不存在的key,则设置key为1
incr key
# 同上,但是做的是减减操作,decr一个不存在key,则设置key为-1
decr key
# 同incr,加指定值 ,key不存在时候会设置key,并认为原来的value是 0
incrby key integer
# 同decr,减指定值。decrby完全是为了可读性,我们完全可以通过incrby一个负值来实现同样效果,反之一样
decrby key integer
# 给指定key的字符串值追加value,返回新字符串值的长度。下面给个例子
append key value
# 返回截取过的key的字符串值,注意并不修改key的值。下标是从0开始的,接着上面例子
substr key start end
List 基本操作
Redis 中的 List 类型与 JAVA 中的 LinxedList 类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索
有序,元素可以重复,插入和删除快,查询速度一般
LPUSH key element ... # 向列表左侧插入一条或者多条数据
LPOP key # 移除并返回列表左侧的第一个元素,没有则返回 nil
RPUSH key element ... # 向列表右侧插入一个或者多个元素
RPOP key # 移除并返回列表右侧的第一个元素
LRANGE key star end # 返回一段角标范围内的所有元素
BLPOP 和 BRPOP # 与 LPOP 和 RPOP 类似,只不过在没有元素时等待指定时间,而不是直接返回 nil
# list 基本操作
# 在key对应list的头部添加字符串元素,返回1表示成功,0表示key存在且不是list类型
lpush key string
# 同上,在尾部添加
rpush key string
# 返回key对应list的长度,key不存在返回0,如果key对应类型不是list返回错误
llen key
# 返回指定区间内的元素,下标从0开始,负值表示从后面计算,-1表示倒数第一个元素 ,key不存在返回空列表
lrange key start end
# 截取list,保留指定区间内元素,成功返回1,key不存在返回错误
ltrim key start end
# 设置list中指定下标的元素值,成功返回1,key或者下标不存在返回错误
lset key index value
# 从key对应list中删除count个和value相同的元素。count为0时候删除全部
lrem key count value
# 在指定 key 的前或者后插入值
linsert key before/after value newValue
# 从list的头部删除元素,并返回删除元素。如果key对应list不存在或者是空返回nil,如果key对应值不是list返回错误
lpop key
# 同上,但是从尾部删除
rpop
Set基本操作
Redis 的 Set 结构与 JAVA 中的 HashSet 类似,可以看做是一个 value 为 null 的 HashMap 因为也是一个 hash 表,因此具备与 HashSet 类似的特征
无序,元素不可重复,查找快,支持交集,并集,差集等功能
SADD key member ... # 向 set 中添加一个或多个元素
SREM key member ... # 移除 set 中的指定元素
SCARD key # 返回 set 中元素的个数
SISMEMBER key member # 判断一个元素是否存在于 set 中
SMEMBERS 获取 set # 中的所有元素
SINTER key1 key2 # 求 key1 和 key2 的交集
SDIFF key1 key2 # 求 key1 和 key2 的差集
SUNION key1 key2 # 求 key1 和 key2 的并集
# Set基本操作
# 添加一个string元素到,key对应的set集合中,成功返回1,如果元素以及在集合中返回0,key对应的set不存在返回错误
sadd key member
# 从key对应set中移除给定元素,成功返回1,如果member在集合中不存在或者key不存在返回0,如果key对应的不是set类型的值返回错误
srem key member
# 删除并返回key对应set中随机的一个元素,如果set是空或者key不存在返回nil
spop key
# 同spop,随机取set中的一个元素,但是不删除元素
srandmember key
# 从srckey对应set中移除member并添加到dstkey对应set中,整个操作是原子的。成功返回1,如果member在srckey中不存在返回0,如果key不是set类型返回错误
smove srckey dstkey member
# 返回set的元素个数,如果set是空或者key不存在返回0
scard key
# 判断member是否在set中,存在返回1,0表示不存在或者key不存在
sismember key member
# 返回所有给定key的交集
sinter key1 key2...keyN
# 同sinter,但是会同时将交集存到dstkey下
sinterstore dstkey key1...keyN
# 返回所有给定key的并集
sunion key1 key2...keyN
# 同sunion,并同时保存并集到dstkey下
sunionstore dstkey key1...keyN
# 返回所有给定key的差集
sdiff key1 key2...keyN
# 同sdiff,并同时保存差集到dstkey下
sdiffstore dstkey key1...keyN
# 返回key对应set的所有元素,结果是无序的
smembers key
Sorted Set基本操作
Redis 的 SortedSet 是一个课排序的 set 集合,与 JAVA 中的 TreeSet 有些类似,但是低层数据结构差异却很大,在SortedSet中的每一个元素都带有一个 score 属性,可以基于 score 属性对应元素排序,低层的实现是一个跳表 (SkipList)加 hash 表
可排序,元素不重复,查询速度快
因为 SortedSet 的可排序特性,经常被用来实现排行榜这样的功能
ZADD key score member # 添加一个或者多个元素到 sorted set ,如果已经存在则更新其 score 值
ZREM key member # 删除 sorted set 中的一个指定元素
ZSCORE key member # 获取 sorted set 中的指定元素的 score 值
ZRANK key member # 获取 sorted set 中的指定元素的排名
ZCARD key # 获取 sorted set 中的元素的个数
ZCOUNT key min max # 统计 score 值在给定范围内的所有元素的个数
ZINCRBY key increment member # 让 sorted set 中的指定元素自增长,步长为指定的 increment 的值
ZRANGE key min max # 按照 score 排序后,获取指定排名范围内的元素
ZRANGEBYSCORE key min max # 按照 score 排序后,获取指定 score 范围内的元素
ZDIFF,ZINTER,ZUNION # 求差集,交集,并集
# 所有的排名默认都是升序排名,如果要降序排名则要在 Z 之后加上 REV 即可,例如 ZRANGE ==> ZREVRANGE
# Sorted Set基本操作
# 添加元素到集合,元素在集合中存在则更新对应score
zadd key score member
# 删除指定元素,1表示成功,如果元素不存在返回0
zrem key member
# 增加对应member的score值,然后移动元素并保持skip list保持有序。返回更新后的score值
zincrby key incr member
# 返回指定元素在集合中的排名(下标),集合中元素是按score从小到大排序的
zrank key member
# 同上,但是集合中元素是按score从大到小排序
zrevrank key member
# 类似lrange操作从集合中去指定区间的元素。返回的是有序结果
zrange key start end
# 同上,返回结果是按score逆序的
zrevrange key start end
# 返回集合中score在给定区间的元素
zrangebyscore key min max
# 返回集合中score在给定区间的数量
zcount key min max
# 返回集合中元素个数
zcard key
# 返回给定元素对应的score
zscore key element
# 删除集合中排名在给定区间的元素
zremrangebyrank key min max
# 删除集合中score在给定区间的元素
zremrangebyscore key min max
Hash基本操作
Hash 类型,也叫散列,其 value 是一个无序字典,类似于 JAVA 中的 HashMap 结构
String 结构是将对象序列化为 JSON 字符串后存储,当需要修改对象某个字段时很不方便
Hash 结构可以将对象中的每个字段独立存储,可以针对单个字段做 CRUD
HSET key field value # 添加或修改 hash 类型的 key 的 field 的值
HGET key field # 获取一个 hash 类型的 key 的 field 的值
HMSET # 批量添加多个 hash 类型的 key 的 field 的值
HMGET # 批量获取多个 hash 类型的 key 的 field 的值
HGETALL # 获取一个 hash 类型的 key 中的所有的 field 的值
HKEYS # 获取一个 hash 类型的 key 中的所有的 field
HVALS # 获取一个 hash 类型的 key 中的所有的 value
HINCRBY # 让一个 hash 类型 key 的字段自增长并且指定步长
HSETNX # 添加一个 hash 类型的 key 的 field 值,前提是这个 field 不存在,否则不执行
# Hash基本操作
# 设置hash field为指定值,如果key不存在,则先创建
hset key field value
# 获取指定的hash field
hget key field
# 获取全部指定的hash filed
hmget key filed1....fieldN
# 同时设置hash的多个field
hmset key filed1 value1 ... filedN valueN
# 将指定的hash filed 加上给定值
hincrby key field integer
# 测试指定field是否存在
hexists key field
# 删除指定的hash field
hdel key field
# 返回指定hash的field数量
hlen key
# 返回hash的所有field
hkeys key
# 返回hash的所有value
hvals key
# 返回hash的所有filed和value
hgetall
redis 通用命令
KEYS # 查看使用模板的所有 KEY ,不建议在生产环境中在设备上去使用
DEL # 删除一个指定的 KEY
EXISTS # 判断 KEY 是否存在
EXPIRE # 给一个 KEY 设置一个有效期,有效期一到这个 KEY 自动删除
TTL # 查看一个 KEY 的剩余有效期 返回 -2 表示该 KEY 已经被删除 -1 表示永久有效
key 的层级格式
Redis 的 key 允许有多个单词形成层级结构,多个单词之间用 ':' 隔开,格式如下
项目名:业务名:类型:id
这个格式并非固定,也可以根据自己的需求来删除或添加词条