Redis
一、Redis简介
1、redis是什么
Redis全名REmote DIctionary Server 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(zset/sorted sets)等类型。
2、redis特点
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
3、Redis与其他key-value存储的不同
- Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
- Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
4、redis应用场景
①配合关系型数据库做高速缓存
高频次,热门访问的数据,可以存储在redis中,降低数据库IO
作为布隆过滤器,抵御网络攻击
②多样的数据结构存储持久化数据
二、Redis安装
1、下载redis
# 需要有wget工具,没有的话安装wget
yum -y install wget
# 下载redis
wget http://download.redis.io/releases/redis-6.2.1.tar.gz
# 解压redis
tar -zxvf redis-6.2.1.tar.gz
2、安装c语言的编译环境
# Centos7 gcc版本默认4.8.3,yum 上版本也是4.8.3,所以无法使用yum进行软件更新,所以使用scl。
# scl软件集(Software Collections),是为了给 CentOS 用户提供一种以方便、安全地安装和使用应用程序和运行时环境的多个(而且可能是更新的)版本的方式,同时避免把系统搞乱
# 安装scl源:
yum install centos-release-scl scl-utils-build
# 安装devtoolset
yum install -y devtoolset-8-toolchain
# 激活gcc版本,使其生效
scl enable devtoolset-8 bash
# 测试gcc版本
gcc --version
# scl命令启用只是临时的,退出shell或重启就会恢复原系统gcc版本,如果要长期使用gcc 8的话,运行如下命令
echo "source /opt/rh/devtoolset-8/enable" >>/etc/profile
3、编译redis
# 进入redis安装好的文件里
cd redis-6.2.1
# 执行make命令开始编译
make
# 如果没有准备好C语言编译环境,make 会报错—Jemalloc/jemalloc.h:没有那个文件
# 解决方案运行 make distclean,安装好c语言编译环境后再执行make
# 跳过make test
make install
4、启动redis
redis安装目录:/usr/local/bin
redis-benchmark:性能测试工具,可以在自己本子运行,看看自己本子性能如何
redis-check-aof:修复有问题的AOF文件,rdb和aof后面讲
redis-check-dump:修复有问题的dump.rdb文件
redis-sentinel:Redis集群使用
redis-server:Redis服务器启动命令
redis-cli:客户端,操作入口
①前台启动redis(不推荐)
# 命令行窗口不能关闭,否则服务器停止
/usr/local/bin/redis-server
②后台启动
# 进入redis安装好的文件里
cd redis-6.2.1
# 拷贝一份redis.conf
mkdir conf
cp ./redis.conf ./conf/
# 修改./conf/redis.conf后台启动设置daemonize no改成yes(第128行)
# 启动redis
/usr/local/bin/redis-server /opt/modules/redis-6.2.1/conf/redis.conf
# 启动客户端
redis-cli
# 多端口启动可以:redis-cli -p6379
# 关闭客户端
redis-cli shutdown
# 多实例关闭,指定端口关闭:redis-cli -p 6379 shutdown
③redis.conf 配置项
序号 | 配置项 | 说明 |
---|---|---|
1 | daemonize no | Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程 |
2 | pidfile /var/run/redis.pid | 当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定 |
3 | port 6379 | 指定 Redis 监听端口,默认端口为 6379 |
4 | rdbcompression yes | 指定存储至本地数据库时是否压缩数据,默认为 yes |
5 | dbfilename dump.rdb | 指定本地数据库文件名,默认值为 dump.rdb |
6 | dir ./ | 指定本地数据库存放目录 |
三、redis命令
1、redis key操作命令
序号 | 命令 | 说明 |
---|---|---|
1 | keys * | 查看当前库所有key,*也可以用于匹配,如a结尾的key:*a。 |
2 | exists <key> | 判断某个key是否存在。 |
3 | type <key> | 返回 key 所储存的值的类型。 |
4 | del <key> | 删除指定的key数据。 |
5 | unlink <key> | 根据value选择非阻塞删除,即仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作。 |
6 | expire <key> <time> | 为给定的key设置过期时间。 |
7 | ttl <key> | 查看还有多少秒过期,-1表示永不过期,-2表示已过期。 |
8 | select <db> | 默认有16个库从0-15。 |
9 | dbsize | 查看当前数据库的key的数量。 |
10 | flushdb | 清空当前库。 |
11 | flushall | 清空全部库。 |
2、Redis value为string类型命令
String是Redis最基本的类型,String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象。
String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M
序号 | 命令 | 说明 |
---|---|---|
1 | set <key> <value> [EX|PX] <time> | 设置指定 key 的值,EX为设置key的超时秒数,PX为设置key的超时毫秒数,与EX互斥。 |
2 | get <key> | 查询对应键值。 |
3 | append <key> <value> | 将给定的value追加到原值的末尾。 |
4 | strlen <key> | 获得对应key的值的长度。 |
5 | setnx <key> <value> | 只有在 key 不存在时 设置 key 的值。 |
6 | incr <key> | 将 key 中储存的数字值增1,只能对数字值操作,如果为空,新增值为1。 |
7 | decr <key> | 将 key 中储存的数字值减1,只能对数字值操作,如果为空,新增值为-1。 |
8 | incrby / decrby <key> <步长> | 将 key 中储存的数字值增减。自定义步长。 |
9 | mset <key1> <value1> <key2> <value2> … | 同时设置一个或多个 key-value对。 |
10 | mget <key1> <key2> <key3> … | 同时获取一个或多个 value 。 |
11 | msetnx <key1> <value1> <key2> <value2> … | 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。原子性,有一个失败则都失败。 |
12 | getrange <key> <起始位置> <结束位置> | 获得值的范围,类似java中的substring,左闭右闭。 |
13 | setrange <key> <起始位置> <value> | 用 value 覆写key所储存的字符串值,从起始位置开始(索引从0开始)。 |
14 | setex <key> <过期时间> <value> | 设置键值的同时,设置过期时间,单位秒。 |
15 | getset <key> <value> | 以新换旧,设置了新值同时获得旧值。 |
3、Redis value为List类型命令
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
List的数据结构为快速链表quickList,数据较少时使用的是一块连续的内存,结构为ziplist,当数据较多时,就会转化为quicklist,将ziplist通过双向指针链接起来
序号 | 命令 | 说明 |
---|---|---|
1 | lpush/rpush <key> <value1> <value2> <value3> … | 从左边/右边插入一个或多个值。 |
2 | lpushx/rpushx <key> <value1> <value2> … | 将一个或多个值插入到已存在的列表的左边/右边。 |
3 | lpop/rpop <key> | 从左边/右边吐出一个值。当没有值时,这个键会被删除。 |
4 | blpop/brpop <key1> <key2> … <timeout> | 从左边/右边吐出一个值。当没有值时,会阻塞列表直到等待超过timeout秒或发现可弹出元素为止。 |
4 | rpoplpush <key1> <key2> | 从key1列表右边吐出一个值,插到key2列表左边。 |
5 | lrange <key> <start> <stop> | 按照索引下标获得元素(从左到右)当start=0,stop=1时展示全部value。 |
6 | lindex <key> <index> | 按照索引下标获得元素(从左到右)。 |
7 | llen <key> | 获得列表长度 。 |
8 | linsert <key> before/after <value> <newvalue> | 在value的前面/后面插入newvalue,如果有多个value的话会在第一个找到的value前/后插入newvalue。 |
9 | lrem <key> <n> <value> | 从左边删除n个value(从左到右)。 |
10 | lset <key> <index> <value> | 将列表key下标为index的值替换成value。 |
11 | ltrim <key> <start> <stop> | 让列表只保留[start,stop]内的元素,不在指定区间之内的元素都将被删除。从0开始。 |
4、Redis value为Set类型命令
Set数据结构是dict字典,字典是用哈希表实现的,redis的set是string类型的无序集合。它底层是一个value为null的hash表
序号 | 命令 | 说明 |
---|---|---|
1 | sadd <key> <value1> <value2> … | 将一个或多个 value 元素加入到集合 key 中,已经存在的 value 元素将被忽略。 |
2 | smembers <key> | 取出该集合的所有值。 |
3 | sismember <key> <value> | 判断集合 key 是否为含有该 value 值,有1,没有0。 |
4 | scard <key> | 返回该集合的元素个数。 |
5 | srem <key> <value1> <value2> … | 删除集合中一个或多个元素。 |
6 | spop <key> | 移除并返回集合中的一个随机元素 |
7 | srandmember <key> <n> | 随机从该集合中取出n个值。不会从集合中删除 。 |
8 | smove <source> <destination> <value> | 将value元素从source集合移动到destination集合。 |
9 | sinter <key1> <key2> | 返回两个集合的交集元素。 |
10 | sunion <key1> <key2> | 返回两个集合的并集元素。 |
11 | sdiff <key1> <key2> | 返回两个集合的差集元素(key1中的,不包含key2中的) |
5、Redis value为Hash类型命令
Redis hash是一个string类型的hash表
序号 | 命令 | 说明 |
---|---|---|
1 | hset <key> <field> <value> | 给 key 集合中的 field 键赋值 value。 |
2 | hget <key> <field> | 从 key 集合的 field 键中取出 value。 |
3 | hgetall <key> | 获取在哈希表中指定 key 的所有字段和值。 |
4 | hmset <key> <field1> <value1> <field2> <value2> … | 批量设置key的值。 |
5 | hmget <key> <field1> <field2> … | 获取所有给定 field 键的值。 |
6 | hexists <key> <field> | 查看哈希表 key 中,给定的 field 键是否存在。 |
7 | hkeys <key> | 列出该hash集合的所有field。 |
8 | hvals <key> | 列出该hash集合的所有value。 |
9 | hincrby <key> <field> <increment> | 为哈希表 key 中的域 field 的值加上增量,当且仅当 field 对应的值可以转化为int。 |
10 | hincrbyfloat <key> <field> <increment> | 为哈希表 key 中的域 field 的值加上增量,当且仅当 field 对应的值可以转化为float。 |
11 | hsetnx <key> <field> <value> | 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。 |
12 | hdel <key> <field1> <field2> … | 删除一个或多个哈希表字段。 |
6、Redis value为Zset类型命令
Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分 score 被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了 。
对于有序集合的底层实现,可以用数组、平衡树、链表等。数组不便元素的插入、删除;平衡树或红黑树虽然效率高但结构复杂;链表查询需要遍历所有效率低。Redis采用的是跳跃表。跳跃表效率堪比红黑树,实现远比红黑树简单。
序号 | 命令 | 说明 |
---|---|---|
1 | zadd <key> <score1> <value1> <score2> <value2> … | 将一个或多个 value 元素及其 score 值加入到有序集 key 当中。 |
2 | zcard <key> | 获取有序集合的成员数 |
3 | zrange <key> <start> <stop> [withscores] | 返回有序集 key 中,下标在[start,stop]之间的元素;带withscores,可以让分数一起和值返回到结果集。 |
4 | zrangebyscore <key> <min> <max> [withscores] [limit] | 返回有序集 key 中,所有 score 值在[min,max]之间的成员。有序集成员按 score 值递增(从小到大)次序排列;limit表示返回前几条数据。 |
5 | zrevrangebyscore <key> <min> <max> [withscores] [limit] | 同上,改为从大到小排列。 |
6 | zincrby <key> <increment> <value> | 为元素的score加上增量。 |
7 | zrem <key> <value> | 删除 key 集合下,指定值的元素 。 |
8 | zcount <key> <min> <max> | 统计该集合,score 值在[min,max]区间内的元素个数 |
9 | zrank <key> <value> | 返回该值在集合中的排名,从0开始。 |
10 | zinterstore <key> <num> <key1> <key2> | 计算给定的一个或多个有序集的交集的前 num 项并将结果集存储在新的有序集合 key 中 |