00-Redis 基础

官网保平安:https://redis.io/

Redis 简介

Redis 是一个开源的、使用 ANSI C 语言编写的、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言 API 的非关系型数据库。

SQL 遵循 ACID 规则。NoSQL(Not Only SQL)一般为分布式,而分布式一般遵循 CAP【一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)】定理。

Redis 是 NoSQL,虽然是单线程(6.0之后提供多线程),但是可处理 1 秒 10w 的并发。因为 Redis 的数据是存在内存中的,所以读写速度非常快,因此 Redis 被广泛应用于缓存方向。另外,Redis 也经常用来做分布式锁。Redis 提供了多种数据类型来支持不同的业务场景。除此之外,Redis 支持事务 、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。

Redis 是一个 key-value 存储系统。和 Memcached 类似,它支持存储的 value 类型相对更多,包括 string(字符串)、list(链表)、set(集合)、zset(sorted set-有序集合)和 hash(哈希类型)。这些数据类型都支持 push/pop、add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,Redis 支持各种不同方式的排序。

与 memcached 一样,为了保证效率,数据都是缓存在内存中。但是 Redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且实现了 master-slave(主从)同步。

Redis 优势

  • 性能极高:因为数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1),Redis 读的速度是 110000 次/s,写的速度是 81000 次/s。
  • 丰富的数据类型:Redis 支持 Strings、Lists、Hashes、Sets 及 Sorted Set 数据类型操作。
  • 支持事务:Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。
  • 丰富的特性:Redis 还支持 publish/subscribe、通知、按 key 设置过期时间,过期后将会自动删除。

为什么要用 Redis?

1、访问速度更快

传统数据库数据保存在磁盘,而 Redis 基于内存,内存的访问速度比磁盘快很多。引入 Redis 之后,我们可以把一些高频访问的数据放到 Redis 中,这样下次就可以直接从内存中读取,速度可以提升几十倍甚至上百倍。

2、高并发

一般像 MySQL 这类的数据库的 QPS 大概都在 4k 左右(4 核 8g) ,但是使用 Redis 缓存之后很容易达到 5w+,甚至能达到 10w+(就单机 Redis 的情况,Redis 集群的话会更高)。

QPS(Query Per Second):服务器每秒可以执行的查询次数;

由此可见,直接操作缓存能够承受的数据库请求数量是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。进而,我们也就提高了系统整体的并发。

3、功能全面

Redis 除了可以用作缓存之外,还可以用于分布式锁、限流、消息队列、延时队列等场景,功能强大!

Redis 为什么这么快 ★★★

  • **完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1)**;
  • 数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;
  • 采用单线程(6.0之后提供多线程),避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
  • 使用 I/O 多路复用模型
  • 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis 直接自己构建了 VM 机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
  • Redis 通信协议实现简单且解析高效。

Redis 与其他 key-value 存储有什么不同

  • Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。
  • Redis 的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
  • Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样 Redis 可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的, 因为他们并不需要进行随机访问。

Memcache 与 Redis 的区别都有哪些共同点和区别

共同点

  1. 都是基于内存的数据库,一般都用来当做缓存使用。
  2. 都有过期策略。
  3. 两者的性能都非常高。

区别

  1. 数据类型:Redis 支持更丰富的数据类型(支持更复杂的应用场景)。Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。Memcached 只支持最简单的 k/v 数据类型。
  2. 数据持久化:Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而 Memcached 把数据全部存在内存之中。也就是说,Redis 有灾难恢复机制而 Memcached 没有。
  3. 集群模式支持:Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 Redis 自 3.0 版本起是原生支持集群模式的。
  4. 线程模型:Memcached 是多线程,非阻塞 IO 复用的网络模型;Redis 使用单线程的多路 IO 复用模型。 (Redis 6.0 针对网络数据的读写引入了多线程)
  5. 特性支持:Redis 支持发布订阅模型、Lua 脚本、事务等功能,而 Memcached 不支持。并且,Redis 支持更多的编程语言。
  6. 过期数据删除:Memcached 过期数据的删除策略只用了惰性删除,而 Redis 同时使用了惰性删除与定期删除。
  7. value 值大小不同。Redis 最大可以达到 1gb。Memecache 只有 1mb。
  8. 速度不同。Redis 的速度比 Memecache 快很多。
  9. 备份不同。Redis 支持数据的备份,也支持 master-slave 模式的数据备份。

其他

一个字符串类型的值能存储最大容量是多少

512M

一个 Redis 实例最多能存放多少的 keys?List、Set、Sorted Set 他们最多能存放多少元素?

理论上 Redis 可以处理多达 2**32 的 keys。

有人进行了实际测试,每个实例至少存放了 2 亿 5 千万的 keys。任何 list、set、和 sorted set 都可以放 2**32 个元素。换句话说, Redis 的存储极限是系统中的可用内存值。

Redis 中数据库默认是多少个 db

Redis 默认有 16 个 db,db0~db15(可以通过配置文件支持更多,无上限),并且每个数据库的数据是隔离的不能共享。

注意:多个数据库之间并不是完全隔离的,比如 FLUSHALL 命令可以清空一个 Redis 实例中所有数据库中的数据。

Redis 如何选择数据库

  • Redis 单机版默认有 16 个数据库,使用 select 1 进行切换。
  • Redis 集群目前无法做数据库选择, 默认在 0 数据库。

Redis 如何设置密码及验证密码

开启:requirepass 1234,认证 auth 1234

查看 Redis 使用情况及状态信息用什么命令?

info

修改配置不重启 Redis 会实时生效吗

针对运行实例,有许多配置选项可以通过 CONFIG SET 命令进行修改,而无需执行任何形式的重启。 从 Redis 2.2 开始,可以从 AOF 切换到 RDB 的快照持久性或其他方式而不需要重启 Redis。

检索 CONFIG GET * 命令获取更多信息。

但偶尔重新启动是必须的,如为升级 Redis 程序到新的版本,或者当你需要修改某些目前 CONFIG 命令还不支持的配置参数的时候。

Redis 使用规范

实际使用 Redis 的过程中,我们尽量要准守一些常见的规范,比如:

  1. 使用连接池:避免频繁创建关闭客户端连接。
  2. 尽量不使用 O(n)指令,使用 O(n) 命令时要关注 n 的数量:像 KEYS *HGETALLLRANGESMEMBERSSINTER/SUNION/SDIFF 等 O(n) 命令并非不能使用,但是需要明确 n 的值。另外,有遍历的需求可以使用 HSCANSSCANZSCAN 代替。
  3. 使用批量操作减少网络传输:原生批量操作命令(比如 MGETMSET等等)、pipeline、Lua 脚本。
  4. 尽量不适用 Redis 事务:Redis 事务实现的功能比较鸡肋,可以使用 Lua 脚本代替。
  5. 禁止长时间开启 monitor:对性能影响比较大。
  6. 控制 key 的生命周期:避免 Redis 中存放了太多不经常被访问的数据。
  7. ……

相关文章推荐:阿里云 Redis 开发规范


00-Redis 基础
https://flepeng.github.io/interview-41-数据库-41-Redis-00-Redis-基础/
作者
Lepeng
发布于
2020年8月8日
许可协议