如何通过使用“缓存”相关技术,解决“高并发”的业务场景案例?

本文介绍了如何通过Redis缓存技术解决高并发业务场景,从Redis基础、深入原理到实际应用,包括Redis的数据类型、持久化机制、主从复制和哨兵集群等,探讨了多级缓存架构设计,以及如何处理缓存灾难问题,如缓存穿透、击穿和雪崩。
摘要由CSDN通过智能技术生成

推荐学习

01 前言

我们将先从Redis、Nginx+Lua等技术点出发,了解缓存应用的场景。通过使用缓存相关技术,解决高并发的业务场景案例,来深入理解一套成熟的企业级缓存架构是如何设计的。

02 Redis基础

2.1 简介

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

它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

Redis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

优势

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

2.2 数据类型

2.2.1 String(字符串)

string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。

string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

redis 127.0.0.1:6379> SET runoob "laowang"
OK
redis 127.0.0.1:6379> GET runoob
"laowang"

2.2.2 Hash(哈希)

Redis hash 是一个键值(key=>value)对集合。

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

每个 hash 可以存储 2^32 -1 键值对(40多亿)。

redis 127.0.0.1:6379> HMSET runoob field1 "Hello" field2 "World"
"OK"
redis 127.0.0.1:6379> HGET runoob field1
"Hello"
redis 127.0.0.1:6379> HGET runoob field2
"World"

2.2.3 List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

列表最多可存储 2^32 - 1 元素 (4294967295, 每个列表可存储40多亿)。

redis 127.0.0.1:6379> lpush runoob redis
(integer) 1
redis 127.0.0.1:6379> lpush runoob mongodb
(integer) 2
redis 127.0.0.1:6379> lpush runoob rabitmq
(integer) 3
redis 127.0.0.1:6379> lrange runoob 0 10
1) "rabitmq"
2) "mongodb"
3) "redis"

2.2.4 Set(集合)

Redis 的 Set 是 string 类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

sadd 命令 :添加一个 string 元素到 key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0。

集合中最大的成员数为 2^32 - 1(4294967295, 每个集合可存储40多亿个成员)。

redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> sadd runoob redis
(integer) 1
redis 127.0.0.1:6379> sadd runoob mongodb
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 0
redis 127.0.0.1:6379> smembers runoob

1) "redis"
2) "rabitmq"
3) "mongodb"

2.2.5 zset(sorted set:有序集合)

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

zadd 命令 :添加元素到集合,元素在集合中存在则更新对应score

redis 127.0.0.1:6379> zadd runoob 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 mongodb
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 0
redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000
1) "mongodb"
2) "rabitmq"
3) "redis"

03 Redis深入:带着问题出发?

3.1 如果让你设计一个KV数据库,该如何设计

对这个问题的思考,将有助于我们从整体架构上去学习Redis。

假设现在我们已经设计好了一个KV数据库,首先如果我们要使用,是不是得有入口,我们是通过动态链接库还是通过网络socket对外提供访问入口,这就涉及到了访问模块。Redis就是通过

通过访问模块访问KV数据库之后,我们的数据存储在哪里?为了保证访问的高性能,我们选择存储在内存中,这又需要有存储模块。存在内存中的数据,虽然访问速度快,但存在的的问题就是断电后,无法恢复数据,所以我们还需要支持持久化操作

有了存储模块,我们还需要考虑,数据是以什么样的形式存储?怎样设计才能让数据操作更优,这就设计到了,数据类型的支持,索引模块。 索引的作用是让键值数据库根据 key 找到相应 value 的存储位置,进而执行操作。

有了以上模块的只是,我们是不是要对数据进行操作了?比如往KV数据库中插入或更新一条数据,删除和查询,这就是需要有操作模块了。

至此我们已经构造出了一个KV数据库的基本框架了,带着这些架构,我们再深入到每个点中去探究,这样就会轻松很多,不会迷失在末枝细节中了。

3.2 Redis为什么那么快?

我们都知道Redis访问快,这是因为redis的操作都是在内存上的,内存的访问本身就很快,另外Redis底层的数据结构也对“快”起到了至关重要的作用。

我们平常所以所说Redis的5种数据结构:String、Hash、Set、ZSet和List指的只是键值对中值的数据结构,而我这里所说的数据结构,指的是它们底层实现。

Redis的底层数据结构有࿱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值