Redis是什么
Redis是一款开源的内存数据结构存储,用作数据库,缓存和消息中间件,支持多种数据结构,如:strings,hashes,lists,sets,带有范围查询的sorted sets ,bitmaps,hyperloglogs,带有半径查询的geospatial Indexes,和stream;
Redis内置了的主从复制,事务,以及不同级别的持久化功能,并通过Sentinel和自动分区的Cluster提供了高可用性;
在redis中可以对这些类型进行原子操作(线程安全);
为了获得优秀的性能,redis把数据存储在内存中,根据实际情况你可以每隔一段时间将数据转存至磁盘或者追加每一个操作指令到log中,来实现持久化;如果只需要用于内存缓存,你可以禁用持久化;
redis还支持异步主从复制和非常快的非阻塞的首次同步,自动重连和部分数据重新同步在遇到网络分裂(异常)时;
Redis使用c编写,可以运行于绝大多数POSIX系统上,例如 Linux,OS X,BSD,而且不需要任何的外部依赖,Linux和OS X是Redis开发和测试最多的两个操作系统,建议使用LInux系统部署,Windows版本没有官方支持。
官网:https://redis.io
为什么需要Redis
可以看出redis和mysql有非常大的区别,主要体现在数据结构和存储方式上,mysql是关系型数据库,存储数据前必须明确定义表结构和数据类型,数据之间可以存在关联关系,而redis中并不需要提前定义数据模型,随时可以添加新的结构到数据库中,redis也不能维护数据间的关系;
NoSQL
这里不得不提到的一个名称就是NoSQL,NoSQL有两种含义
No Relations和Not Only SQL,通常我们谈及NoSQL都是泛指非关系型数据库,即数据之间没有关系;
NoSQL伴随着web2.0开始崛起,web2.0时代(要处理大规模的数据,且经常存在非结构化的数据)传统数据库表现的力不从心,而且出现一系列难以攻克的问题;
关系型与非关系型的对比:
对比项 | 关系型 | 非关系型 |
---|---|---|
事务支持 | 完整的事务支持,非常适合存储系统关键数据 | 大多没有完整的ACID事务支持,数据的一致性较差,不支持回滚 |
存储方式 | 完整数据存储在磁盘上,大多数操作都需要读写磁盘 | 数据存储在内存中,仅在持久化时读写磁盘,且读写磁盘操作通常是非常少的 |
存储结构 | 数据必须是结构化的,数据表需要预先定义好,可靠性,稳定性高,和维护性高,但当需要修改已有结构时非常的麻烦 | 存储非结构化数据,不需要定义数据结构,任何时候任何地方都可以插入任何类型的数据,非常灵活,很容易适应数据类型和结构的变化 |
高性能 | 一方面磁盘读写导致速度慢另一方面由于需要保证强一致性,通常会对需要并发操作的数据加锁 | 直接对读写内存中的数据速度是非常快的,另外由于不需要保证强一致性,操作不需要加锁,效率非常高 |
扩展性 | 整体效率依赖于IO速度,由于数据需要保证数据之间的一致性,且数据具备固定的结构,横向扩展困难,分库分表实施困难,且无法通用 | 没有了固定存储结构,没有了强一致性要求,系统可以轻松的进行横向扩展,容易实现分布式,向资源池添加新的计算资源即可实现扩展 |
查询 | 通过结构化查询语言(SQL)来完成,根据表中定义的key,来优化查询速度,可实现复杂的连表查询语句 | 各个不同的NoSQL没有统一的标准,数据通常通过key来进行精准查询,无法实现太复杂的查询逻辑 |
通过对比可以发现NoSQL和关系型数据库各自有各自的优缺点,那么在实际运用中该如何选择呢?
一定要强调的是,两者不是非此即彼的关系,而是优势互补,通常我们把项目的关键数据(必须需要保证ACID)放在关系型数据库中,而对于一些临时的,非关键性的,访问频率非常高的数据放在NoSQL中;另外Redis也经常用于消息中间件;
NoSQL的分类:连接
redis的典型应用场景
-
缓存(数据查询、短连接、新闻内容、商品内容等等)。
-
分布式集群架构中的session分离。
-
聊天室的在线好友列表。
-
任务队列。(秒杀、抢购、12306等等)
-
应用排行榜。
-
网站访问统计。
-
数据过期处理(可以精确到毫秒)
安装
安装过程:链接
启动
-
直接运行redis-server可在前台启动服务端,但该方式将导致当前shell被占用无法执行其他操作,除非终止redis的运行....
-
后台进程模式启动,该方式可将redis运行与后台,需要先修改配置文件
3.指定使用redis.conf配置文件启动(先进入bin目录下)
./redis-server redis.conf
#利用客户端连接测试
./redis-cli
#看见如下内容表示已经服务端已经正常运行
停止
- 如果是前端方式启动的服务只需要ctrl+c即可关闭服务器端
- 后台进程模式,需要通过redis-cli客户端来关闭
#关闭运行在localhost上的redis服务
./redis-cli shutdown
#关闭运行在指定地址上的redis服务
./redis-cli -h 127.0.0.1 shutdown
3.强制停止,通过kill命令直接强行结束redis服务端进程,该方式存在不稳定性,生产环境勿用
#查询进程id
ps aux|grep redis
#根据进程id结束服务
kill 进程id
redis-cli连接服务器
语法: redis-cli -h 主机地址 -p 端口
其中主机地址和端口号均可省略 默认主机为localhost
,默认端口为:6379
常用数据类型及相关操作
命令 | 含义 |
---|---|
与数据类型无关 | |
KEYS pattern | 获取当前库中所有匹配的key,可用* ,[] |
EXISTS key | 判断key是否存在 |
DEL key | 删除某个键值对 |
TYPE key | 获取数据类型 |
rename oldkey newkey | 对 key 重命名,如果 newkey 存在则覆盖 |
renamenx oldkey newkey | 对 key 重命名,newkey 存在则取消操作 |
randomkey | 随机返回一个key |
move key db-index | 移动键值对到某个数据库 |
String(动态数组) | |
set key value | 新增/更新数据 |
get key | 获取键值对 |
INCR key | 使value自增,仅在数据为数字时有效 |
DECR key | 使value自减,仅在数据为数字时有效 |
INCRBY key increment | 使value增加指定值,仅在数据为数字时有效 |
DECRBY key increment | 使value减少指定值,仅在数据为数字时有效 |
INCRBYFLOAT key increment | 使value增加指定浮点值,仅在数据为数字时有效 |
APPEND key value | 在字符后面拼接内容 |
STRLEN key | 获取长度 |
MSET | 新增多个键值对 |
MGET | 获取多个键的值 |
Hash(ziplist/hashtable) | |
HSET key field value | 若key不存在则新增hash,再在其中添加属性和值,若field存在则更新 |
HGET key field | 获取某个field |
HMSET key field1... | 同一个key多个字段赋值 |
HMGET key field1 ... | 同一个KEY多个字段取值 |
HGETALL key | 获取KEY的所有字段和所有值 |
HEXISTS key field | 字段是否存在 |
HSETNX key field value | 当字段不存在新增属性和值 |
HINCREBY key field increment | 自增 |
DEL key field1 | 删除指定KEY的一个或多个字段。 |
HKEYS key | 获取所有属性名 |
HVALS key | 获取所有属性值 |
HLEN key | 获取field数量 |
List(双向链表) | |
(LPUSH/RPUSH) key value1 value2 | 添加数据到左边或是右边 |
(LPOP/RPOP) key | 弹出最左边或最右边的元素 |
LLEN key | 列表元素个数 |
LRANGE start end | 获取列表的子列表,包含 start 和 end。支持负数索引。-1 表示最后一个元素,-2 表示倒数第二个元素。 |
LREM key count value | 从这个列表参数值为 value 的count个元素,count为0全删 |
LINDEX key index | 获取指定索引对应的值 |
LSET key index value | 更新索引的值,index不存在则异常 |
LINSERT key BEFORE/AFTER value1 value2 | 从列表头开始遍历,发现值为 value1 时停止,将 value2 插入,根据 BEFORE 或者 AFTER 插入到 value1 的前面还是后面。 |
RPOPLPUSH list1 list2 | 将列表 list1 的右边元素删除,并把该与元素插入到列表 list2 的左边。原子操作。 |
Set(哈希表) | |
SADD key value | 增加 |
SREM key value | 删除 |
SMEMBERS key | 获取全部元素 |
SISMEMBER key value | 判断是否存在某个元素 |
SPOP key | 随机弹出一个元素 |
SDIFF key1 key2 | 差集 |
sinter key1 key2 | 交集 |
SUNION key1 key2 | 并集 |
Zset(跳表优化过的单链表) | |
ZADD key sorce1 value1 | 新增分数和值 |
ZSCORE key value | 获取元素的分数 |
ZRANGE key start stop [WITHSCORE] | 获取排名在 start 和 end 之间的元素列表,包含 start 和 end; WITHSCORE显示分数 |
ZRANGEBYSCORE key min max [WITHSCORE] [LIMIT offset count] | 获取分数在 min 和 max 之间的元素列表。含两头; |
ZINCRBY key increment value。 | 指定的有序集合的值为 value 的元素的分数 +increment |
ZCARD key | 获取集合中元素的数量 |
ZCOUNT key min max | 获取指定分数范围内的元素个数 |
ZREM key value1 value2... | 删除一个或多个元素 |
ZREMRANGEBYRANK key start end | 删除排名在 start 和 end 中的元素。 |
ZREMRANGEBYSCORE key min max | 删除分数在 min 和 max 中的元素 |
ZRANK key value | 获取 value 在该集合中的从小到大的排名。 |
ZREVRANK key value | 获取 value 在该集合中从大到小的排名 |
zrevrange key start end | 获取排名在 start 和 end 之间的元素列表,顺序反转 |
更多操作参考官网:连接
redis持久化
Redis提供两种不同的持久化方式
- RDB持久化会按照指定的时间间隔为数据创建快照并写入磁盘;
- AOF持久化会记录服务器接收到的每一个写数据指令到文件中,这些指令将在服务器重启时进行重放,以此来重建原始数据,AOF产生的命令格格式与Redis本身的命令格式完全相同,并采用仅追加的方式,日志文件太大时,Redis会在后台重写日志;
- 如果希望数据仅在Redis运行期间有效则可以完全禁用持久化来使效率最大化;
RDB快照
优点:
-
RDB是表示某个时间点的非常紧凑的单个文件,RDB文件非常适合用于数据备份,例如(每天保存一次RDB),这可以在灾难发生后轻松地恢复数据;
-
RDB最大限度的保证了Redis的性能,因为父进程唯一要做的就是fork一个子进程去完成剩下的所有工作,父进程不会执行任何的I/O操作;
-
与AOF相比,在数据量较大的情况下RDB能够更快的重启;
缺点:
- 丢失数据,如果希望将数据丢失的可能性(异常停止,断电)降到最低,则RDB不够好,虽然可以配置多个不同的保存点如:(5分钟后,1000次写操作后),通常是5分钟或更长时间后,但是Redis在这个保存点之前因为任何原因导致异常关闭,则将丢失最新的数据;
- RDB需要经常的fork子进程才能将数据持久化到磁盘上,如果数据量很大,该过程可能很耗时,若数据量大且CPU性能不佳,则可能导致Redis停止响应客户端的请求几毫米甚至几秒,虽然AOF重写日志也需要fork子进程但是,你可以调整重写日志的频率;
配置:
默认配置位于配置文件第287:
每个保存点第一个数字为时间间隔,第二个为写操作次数,当两个条件同时满足时则更新快照,频率高影响性能,太低则低丢失更多数据,需按照实际情况斟酌;
保存点可配置多个,如默认配置,更新快照的频率随着数据操作频率的增长而增长,可以尽可能的减少数据丢失,同时在数据操作频率低的时候,减少快照的更新操作;
AOF日志
优点:
-
使用AOF时Redis能提供更好的持久化,尽可能的减少数据丢失;可使用不同的fsync(文件同步)策略包括:完全没有fsync,每秒fsync,每个查询fsync。使用默认策略时(每秒),每秒的写入性能仍然很好;
-
AOF日志是仅追加的日志,即时断点也不会损坏文件,即时由于某种原因以外停止,导致写入了残缺的指令,redis-check-aof工具也能修复日志文件;
-
AOF文件过大时,Redis会在后台重写AOF,重写是安全的,Redis会继续追加操作指令到旧的文件,同时根据当前数据生成重建所需的最精简指令;等第二个文件准备好后Redis会切换至新的日志文件并开始追加到新文件;
-
AOF文件的指令格式非常简单,可以轻松的导出AOF,就像导出sql一样简单,这样你可以轻松的通过AOF文件恢复数据,例如错误的执行了删除所有数据的指令,只要重写操作没有触发,只需要删除最后的语句重新启动Redis;
缺点:
- 对于同样的数据,AOF文件通常大于等效的RDB文件。
- 根据具体的fsync策略,AOF可能比RDB慢。(通常,在将fsync设置为每秒的情况下,性能仍然很高,在禁用fsync的情况下,即使在高负载下,它也与RDB一样快) 虽然如此,在巨大的写负载的情况下,RDB仍然能够尽可能保证最大延迟。
配置:
启用AOF: 默认情况下AOF是禁用的,配置文件第1038行,将no修改为yes
#appendonly no
appendonly yes
文件同步策略,配置文件1067行
appendfsync always #每执行一个写操作立马写入文件并完成磁盘同步
appendfsync everysec #每隔一秒将写操作写入文件并完成磁盘同步
appendfsync no #将写操作指令写入后,等待操作系统自动完成磁盘同步
AOF文件重写配置,配置文件1110行:
auto-aof-rewrite-percentage 100 #达到原始文件多少比例
auto-aof-rewrite-min-size 64mb #最小重写大小
AOF文件不完整(写入过程中意外关闭)时是否允许启动,配置文件1135行
aof-load-truncated yes
通常情况下AOF完整度是比RDB高的,所以重启后读取文件时,AOF优先于RDB;
另外当你对配置文件非常熟悉时完全可以创建一个空文件,添加需要修改的配置即可;