Redis简介和数据结构

目录

简介

进入之后身份认证才能使用

优点

用途:

数据结构

string

string自动扩容

Redis中的简单动态字符串(SDS)具有以下优点:

SDS数据的编码格式

比较:

string 常用操作

分布式锁

使用情况,保证接口幂等性 ?

分布式锁的应用???

list

常用操作

早期版本

压缩列表

优点

缺点

快速链表(quiklist)

set

set常用操作

set应用???

zset有序集合

存储结构

跳跃列表(skipList)

哈希散列表

存储结构


简介

Redis是一个开源的内存中数据结构存储系统,通常用作数据库、缓存和消息代理。它支持各种数据结构,包括字符串、哈希、列表、集合等,并提供了丰富的功能,如事务、持久化、发布/订阅等。

  1. 内存中数据结构存储系统:Redis主要将数据存储在内存中,这使得它具有非常高的读写速度。它通过使用持久化技术来保证数据在重启后不会丢失,因此即使是存储在内存中,也能够满足持久化的需求。

  2. 数据库、缓存和消息代理:Redis可以用作多种用途,包括传统数据库的替代品、缓存系统和消息代理。作为数据库,它可以存储各种类型的数据,并支持复杂的数据结构操作;作为缓存,它可以提供快速的数据访问,减轻后端数据库的压力;作为消息代理,它支持发布/订阅模式,可以用于实时通信和事件驱动架构。

  3. 支持多种数据结构:Redis支持多种数据结构,包括字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等。这些数据结构能够满足不同场景下的数据存储和操作需求。

  4. 丰富的功能:除了基本的数据存储和检索功能外,Redis还提供了许多高级功能,如事务(Transaction)、持久化(Persistence)、发布/订阅(Pub/Sub)等。这些功能使得Redis在各种应用场景下都能发挥重要作用,并且具有很高的灵活性和扩展性。

总的来说,Redis是一个功能强大、性能优异的内存中数据存储系统,适用于各种场景下的数据管理和应用开发。

安装

sudo apt install redis-server

进入之后身份认证才能使用

redis-cli
auth 123456

优点

  1. 高性能: Redis是一个内存数据库,操作在内存中进行,因此具有快速的读写速度。

  2. 数据多样性: 支持不同类型的数据结构,如字符串、哈希、列表、集合、有序集合等,以及Bitmap和GEO地理信息等特殊数据类型。

  3. 持久化: 支持持久化数据到硬盘,可以根据需求选择RDB快照或者AOF日志文件的方式进行持久化。

  4. 发布/订阅模式: 支持消息代理模式,可以实现发布/订阅功能,方便实现消息通信。

  5. 分布式缓存: 支持主从复制和高可用性,可以搭建分布式缓存系统,提高系统的可靠性和容错性。

  6. 事务支持: 支持事务操作,可以将多个命令打包成一个原子操作进行执行,但不支持回滚。

  7. 功能丰富: 提供丰富的功能,如脚本执行(通过Lua脚本),可以实现复杂的业务逻辑。

用途:

  1. 排行榜: 使用有序集合(Sorted Set)数据类型,将每个成员的分数作为排名依据,可以通过自动排序功能实现排行榜功能。

  2. 限速器/计数器: 使用INCR命令对一个键进行自增操作,可以实现计数器功能。例如,可以将某个操作的频率限制在一定的速率内。

  3. 推送: 使用SET命令设置键值对,然后通过PUBLISH命令将消息推送给订阅者,实现简单的消息推送功能。

  4. 消息队列: 使用RPUSH命令向列表尾部添加消息,然后使用LPOP或者BLPOP命令从列表头部获取消息,可以实现基本的消息队列功能。LBPOP是一个阻塞命令,会在列表为空时等待直到有消息到来。

  5. 会话一致性: 可以使用Redis作为会话存储,将会话信息存储在Redis中,实现会话的统一管理和一致性。

MEMCATCH

数据结构

五种基础类型:

string

int类型的编码如果超过长度就会转化为string类型

SDS简单动态字符串:

基本结构结构体

struct sdshdr{//记录buf数组中已使用字符的数量,等于 SDS 保存字符串的长度int len;//记录 buf 数组中未使用的字符数量int free;//字符数组,用于保存字符串char buf[];
}
// 存储 “hello”
len:5
free:0
buf:['H','e','l','l','o','\0']

如上观察所得:

Redis 每次给 string 分配的空间都要大于字符串实际占用的空间,这样就在一定程度上提升了 Redis string 存储的效率,比如当字符串长度变大时,无需再重新申请内存空间。

string自动扩容

当字符串所占空间小于 1MB 时,Redis 对字符串存储空间的扩容是以成倍的方式增加的;而当所占空间超过 1MB 时,每次扩容只增加 1MB。Redis 字符串允许的最大值字节数是 512 MB。

Redis中的简单动态字符串(SDS)具有以下优点:

  1. 获取字符串长度的时间复杂度为O(1): SDS通过保存字符串的长度信息,使得获取字符串长度的操作时间复杂度为O(1),无论字符串长度多长,都能够在常数时间内完成。

  2. 安全的API: Redis的SDS API设计安全,函数使用是安全的,避免了由于字符串操作而引发的内存越界等问题。

  3. 保存二进制数据: SDS不仅可以保存文本数据,还可以保存二进制数据,因为SDS使用了类似C语言中的字符数组来存储数据,所以可以保存任意类型的数据,包括文本和二进制数据。

SDS数据的编码格式

在Redis中,简单动态字符串(SDS)可以存储文本数据,也可以存储二进制数据。在存储二进制数据时,Redis会使用 embstr(embedded string)或者 raw 编码来存储。

  • Embstr(嵌入式字符串): 当字符串长度较短(小于等于39字节,不同版本有所不同)时,Redis会选择使用 embstr 编码,将字符串直接存储在 SDS 结构体中,而不会进行额外的内存分配。这种方式节省了内存,提高了效率。

  • Raw 编码: 当字符串长度超过39字节时,Redis会使用 raw 编码,将字符串存储在单独的堆内存中,并在 SDS 结构体中保存指向堆内存的指针。这种方式适用于较长的字符串,可以避免嵌入式字符串带来的额外内存消耗。

比较:
  • embstr 编码创建字符串对象时,调用一次内存分配函数,raw调用两次

  • embstr 编码释放字符串对象时,调用一次内存释放函数,raw 调用两次

  • embstr 编码的字符串对象保存在一块连续的内存中,可以更好地利用 CPU 缓存提升性能

tips:

如果修改数据类型会怎样变换,会从embstr类型转为raw类型

string 常用操作

set设置字符串
get读取字符串
incr自增
decr自减
exists判断key是否存在
strlen返回字符串长度
del删除key
exprie设置过期时间
ttl查看剩余时间
sentnx不再存在就插入(成功返回(1))

分布式锁

在分布式系统中,当不同进程或线程一起访问共享资源时,会造成资源争抢,如果不加以控制的话,就会引发程序错乱。此时使用分布式锁能够非常有效的解决这个问题,它采用了一种互斥机制来防止线程或进程间相互干扰,从而保证了数据的一致性。

SETNX buy_lock value

setnxl buy 【接口名】 value 【time -》【过期时间】】

这样的命令来尝试获取名为 buy_lock 的锁。如果返回值是 1,表示成功获取了锁,可以执行后续的操作;如果返回值是 0,表示锁已经被其他客户端持有,需要等待或进行其他处理。

tip

设置过期时间:在设置分布式锁时,可以同时设置一个过期时间,以防止锁被持有的客户端出现异常或挂掉,导致锁无法正常释放而产生死锁问题。在 Redis 中,你可以使用 EXPIRE 命令来为锁设置一个过期时间,确保即使锁没有被主动释放,也能在一定时间后自动过期释放。

使用情况,保证接口幂等性 ?

Redis 分布式锁有很对应用场景,举个简单的例子,比如春运时,您需要在 12306 上抢购回家火车票,但 Redis 数据库中只剩一张票了,此时有多个用户来预订购买,那么这张票会被谁抢走呢?Redis 服务器又是如何处理这种情景的呢?在这个过程中就需要使用分布式锁。

分布式锁的应用???

分布式锁在各种场景下都有广泛的应用:

  1. 短链接服务:在短链接服务中,当多个用户同时请求生成短链接时,为了避免生成相同的短链接或者保证短链接的唯一性,可以使用分布式锁来确保同一时刻只有一个请求能够成功生成短链接。

  2. 会话存储:在分布式系统中,需要存储用户的会话信息,以实现用户登录状态的管理和跨服务的会话共享。使用分布式锁可以确保在写入或更新会话信息时的数据一致性和并发安全。

  3. 限流控制:在防止被恶意攻击或者保护服务稳定性的情况下,可以使用分布式锁来实现限流控制。例如,限制某个接口每秒的请求次数,通过分布式锁来控制并发请求的数量,避免服务被过载或者被恶意攻击。

list

常用操作

Redis中的列表(list)是一种支持双向操作的数据结构,类似于链表。它允许在列表的头部或尾部进行快速的添加和删除操作。这里是Redis列表的一些常用操作:

  1. 添加元素:

    • LPUSH key value [value ...]:向列表头部插入一个或多个元素。
    • RPUSH key value [value ...]:向列表尾部插入一个或多个元素。
  2. 删除元素:

    • LPOP key:从列表头部弹出一个元素。
    • RPOP key:从列表尾部弹出一个元素。
    • LREM key count value:从列表中删除指定数量的特定值。
  3. 获取元素:

    • LINDEX key index:根据索引获取列表中的元素,负数索引从列表尾部开始计数。
    • LRANGE key start stop:获取列表指定范围的元素。
  4. 设置元素:

    • LSET key index value:设置列表中指定索引处的值。
  5. 列表长度:

    • LLEN key:获取列表的长度。
  6. 删除列表:

    • LTRIM key start stop:保留列表指定范围内的元素,删除其他部分。

早期版本

如果列表元素个数小于512,采用压缩列表

列表每个元素的值都小于64字节

就会使用压缩列表ziplist

否则使用快速链表quicklist

压缩列表

  • 1、zlbytes:压缩列表的字节长度,占4个字节,因此压缩列表最长(2^32)-1字节;
  • 2、zltail:压缩列表尾元素相对于压缩列表起始地址的偏移量,占4个字节;
  • 3、zllen:压缩列表的元素数目,占两个字节;那么当压缩列表的元素数目超过(2^16)-1怎么处理呢?此时通过zllen字段无法获得压缩列表的元素数目,必须遍历整个压缩列表才能获取到元素数目;
  • 4、entryX:压缩列表存储的若干个元素,可以为字节数组或者整数;entry的编码结构后面详述;
  • 5、zlend:压缩列表的结尾,占一个字节,恒为0xFF

下面是entry每个元素的格式:

previous字段 为1Byte/5Byte

压缩列表(Compressed List)在存储和操作数据时具有一些优点,但同时也存在一些缺点。让我们更深入地探讨这些优点和缺点。

优点
  • 内存紧凑: 压缩列表通过减少冗余元数据和指针来节省内存空间。这种紧凑的结构特别适用于存储小型数据和少量元素。

  • 高效存储: 由于压缩列表以连续存储的方式组织数据,因此它在存储效率和内存占用上表现良好。

  • 灵活性: 压缩列表可以存储不同类型的数据,且不需要为每个元素额外分配内存空间,如链表中的指针或对象引用。

缺点
  • 不能保存过多元素: 压缩列表的结构在一定数量的元素下是高效的,但是当元素数量超出一定限度时,列表可能需要扩展和重组,导致性能下降。更大的数据集需要更多的内存和计算资源。

  • 不能保存过大的元素: 如果压缩列表中的某个元素非常大,可能会导致整个列表需要重新分配内存空间,称为连锁更新(Chain Update)。这是因为在压缩列表中,节点是连续存储的,改变一个节点可能影响整个列表的布局。

  • 不适合频繁修改: 由于压缩列表是紧凑存储的,插入和删除操作可能涉及重新排列整个列表,因此在频繁修改的场景下,效率可能低于其他数据结构,如链表。

  • 搜索和索引性能受限: 压缩列表的结构可能不适合复杂的搜索和索引操作。它通常适用于简单的遍历和查找,但不适用于需要高效索引的数据集。

快速链表(quiklist)

quicklist其实就是一个分段的ziplist,为什么这么说呢?其实quicklist存储数据基本单位是quicklistNode,每个quicklistNode的内容区就是以ziplist数据结构存储的。

 

set

Redis set (集合)遵循无序排列的规则,集合中的每一个成员(也就是元素,叫法不同而已)都是字符串类型,并且不可重复。Redis set 是通过哈希映射表实现的,所以它的添加、删除、查找操作的时间复杂度为 O(1)。集合中最多可容纳 2^32 - 1 个成员(40 多亿个)

set常用操作

  • sadd:添加新元素

  • smembers:列出集合中所有元素

  • sismember:判断元素是否在集合中

  • scard:返回集合中元素个数

  • srem:移除集合中一个或多个元素,如果移除的不存在就不处理

  • sinter:对两个集台求交集

  • sunion:对两个集合求并集

  • sdiff:对两个集合求差集

  • setnx:向 Redis 中添加一个 key,只用当 key 不存在的时候才添加并 返回1,存在则不添加返回 0

set应用???

在Redis中,Set是一种无序、不重复的数据集合,它的应用非常广泛。

  1. 集合运算:Redis提供了一系列的集合运算命令,如并集(Union)、交集(Intersection)、差集(Difference)等,可以对多个Set进行操作,得到新的集合结果。

  2. 标签(Tagging):可以将Set用于标签系统,每个元素代表一个标签,可以方便地对对象进行分类和检索。

  3. 好友关系:可以使用Set来表示用户的好友关系,每个用户的好友列表可以用一个Set来存储,方便进行好友相关操作,如查找共同好友、计算两个用户的共同好友数等。

  4. 唯一值存储:由于Set中的元素是唯一的,可以将Set用于存储唯一值,如网站的访问IP地址、用户的行为记录等。

  5. 实时统计:可以利用Set来进行实时统计,比如统计网站独立访客数、活跃用户数等。

  6. 过滤器:可以将Set用作过滤器,比如用于去重、检查某个元素是否存在等。

  7. 兴趣标记:可以将Set用于存储用户的兴趣标记,比如用户喜欢的电影、音乐等,方便进行个性化推荐。

zset有序集合

Redis zset(有序集合)中的成员是有序排列的,它和 set 集合的相同之处在于,集合中的每一个成员都是字符串类型,并且不允许重复;而它们最大区别是,有序集合是有序的,set 是无序的,这是因为有序集合中每个成员都会关联一个 double(双精度浮点数)类型的 score (分数值),Redis 正是通过 score 实现了对集合成员的排序。

存储结构

有序集合(zset)同样使用了两种不同的存储结构,分别是 zipList(压缩列表)和 skipList(跳跃列表),当 zset 满足以下条件时使用压缩列表:

  • 成员的数量小于128 个;
  • 每个 member (成员)的字符串长度都小于 64 个字节。

当 zset 使用压缩列表保存数据时,entry 的第一个节点保存 member,第二个节点保存 score。依次类推,集合中的所有成员最终会按照 score 从小到大排列。

当不满足使用压缩列表的情况时就使用跳跃列表

跳跃列表(skipList)
typedef struct zskiplistNode {// 后退指针struct zskiplistNode *backward;// 分值 权重double score;// 成员对象robj *obj;// 层struct zskiplistLevel {// 前进指针struct zskiplistNode *forward;// 跨度unsigned int span;} leval[];
} zskiplistNode;typedef struct zskiplist {// 表头节点和表尾节点struct zskiplistNode *header, *tail;// 表中节点的数量unsigned long length;// 表中层数最大的节点的层数int leval;
} zskiplist;
  1. zskiplistNode 结构体:

    • backward:指向前一个节点的指针,用于向前遍历跳跃表。
    • score:节点的分值或权重,用于有序集合中排序节点。
    • obj:成员对象,实际存储在节点中的值。
    • leval:表示节点的层级信息的数组,包括前进指针和跨度(表示跨越的节点数量)。
  2. zskiplist 结构体:

    • header, tail:指向跳跃表头节点和尾节点的指针,用于快速访问跳跃表的起始和结束位置。
    • length:跳跃表中节点的数量,用于记录表的大小。
    • leval:表中层数最大的节点的层数,表示跳跃表的最大层级。

哈希散列表

Redis hash(哈希散列)是由字符类型的 field(字段)和 value 组成的哈希映射表结构(也称散列表),它非常类似于表格结构。在 hash 类型中,field 与 value 一一对应,且不允许重复。

存储结构

hash 类型是 Redis 常用数据类型之一,其底层存储结构有两种实现方式。

第一种,当存储的数据量较少的时,hash 采用 ziplist 作为底层存储结构,此时要求符合以下两个条件:

  • 哈希对象保存的所有键值对(键和值)的字符串长度总和小于 64 个字节。
  • 哈希对象保存的键值对数量要小于 512 个。

当无法满足上述条件时,hash 就会采用第二种方式来存储数据,也就是 dict(字典结构),该结构类似于 Java 的 HashMap,是一个无序的字典,并采用了数组和链表相结合的方式存储数据。在 Redis 中,dict 是基于哈希表算法实现的,因此其查找性能非常高效,其时间复杂度为 O(1)。

**哈希散列表也会有哈希冲突的现象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Dark Reader:夜间模式,启动!

名人说:一点浩然气,千里快哉风。 ——苏轼 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、介绍二、下载安装1、Chrome应用商店(需科学)2、第三方直链下载 三、使…

Pygame简单入门教程(绘制Rect、控制移动、碰撞检测、Github项目源代码)

Pygame简明教程 引言:本教程中的源码已上传个人Github: GItHub链接 视频教程推荐:YouTube教程–有点过于简单了 官方文档推荐:虽然写的一般,但还是推荐! Navigator~ Pygame简明教程安装pygame一、代码框架二、案件输入…

五一开始内卷前端,如何迅速的一个月内找到工作!

写在前面 五一过了代表新的一年不知不觉过了半年了,各位工作找到怎么样,有没有在工作中遇到解决不了的问题,这些问题后面怎么处理了呢? hello大家好,我又又又来了,今天纯干货,上班的朋友适当摸…

Linux下的I2C通信

I2C通信: 一.硬件初识: IIC(inter-intergrated-Circu):内部集成总线 四线通讯:SCL,SDA,GND,VCC,串行,半双工 I2C 总线是同步,串行,半双工通信总线。 I2C 总线由时钟线 SDA 和 SCL 两根信号线构成。并且都有上拉电阻。确保总线空闲状态为高电平。 I2C 总线支持多…

ElasticSearch 与 OpenSearch:拉开性能差距

Elasticsearch 与 OpenSearch:扩大性能差距 对于任何依赖快速、准确搜索数据的组织来说,强大、快速且高效的搜索引擎是至关重要的元素。对于开发人员和架构师来说,选择正确的搜索平台可以极大地影响您的组织提供快速且相关结果的能力。在我们…

揭秘抖音快速涨10000粉的方法:巨量千川投流让你轻松快速增粉

抖音已经成为了当今社交平台的热门之一,而如何快速涨粉已经成为了很多人关注的焦点。本文将揭秘一种高效的方式——巨量千川投流,通过官方真实流量和真实粉丝,每天快速涨关注,实现快速增粉1000~10万。 巨量千川投流是一种专业的抖…

必读干货!国内验证签发的SSL证书六大优势

JoySSL官网 注册码230918 国内验证签发的SSL证书,作为网络安全基础设施的重要组成部分,对于维护互联网数据安全、保障用户隐私、提升网站信誉度具有不可小觑的作用。特别是在当前数字化转型加速、数据合规要求日益严格的背景下,选择国内验证签…

路由的基本使用

目录 一、VueRouter介绍 二、VueRouter的使用 三、注意 一、VueRouter介绍 VueRouter是Vue官方的一个路由插件,是一个第三方包。 作用:修改地址栏路径时,切换显示匹配的组件 官网:Vue Router (vuejs.org) 二、VueRouter的使用 注意&am…

Vue 3.3 编译宏 vue3.3新增了一些语法糖和宏,包括泛型组件、defineSlots、defineEmits、defineOptions

Vue 3.3新增了一些语法糖和宏&#xff0c;包括泛型组件、defineSlots、defineEmits、defineOptions defineProps 父组件传参 <template><Child name"my"></Child> </template> <script setup lang"ts"> import Child fro…

Linux学习笔记4---点亮LED灯(汇编裸机)

本系统学习利用的是正点原子的阿尔法mini开发板&#xff0c;本系列的学习笔记也是按照正点原子的教程进行学习&#xff0c;但并不是利用虚拟机进行开发&#xff0c;而是使用Windows下的子系统WSL进行学习。 因为 Cortex-A 芯片一上电 SP 指针还没初始化&#xff0c;C 环境还没准…

【C++】零钱兑换的始端---柠檬水找零

欢迎来CILMY23的博客 本篇主题为 零钱兑换的始端---柠檬水找零 个人主页&#xff1a;CILMY23-CSDN博客 个人专栏系列&#xff1a; Python | C | C语言 | 数据结构与算法 感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言&#xff1a; 柠檬水找…

嘴尚绝卤味:传承经典,缔造美食新风尚

卤味&#xff0c;作为中国传统美食的代表之一&#xff0c;历经千年的传承与发展&#xff0c;早已成为无数食客餐桌上的宠儿。而在这个美食盛行的时代&#xff0c;嘴尚绝卤味凭借其独特的口感和精湛的工艺&#xff0c;成为卤味市场中的佼佼者&#xff0c;引领着卤味文化的新潮流…

图数据库 之 Neo4j 与 AI 大模型的结合绘制知识图谱

引言 随着信息时代的到来&#xff0c;海量的文本数据成为了我们获取知识的重要来源。然而&#xff0c;如何从这些文本数据中提取出有用的信息&#xff0c;并将其以可视化的方式展示出来&#xff0c;一直是一个具有挑战性的问题。近年来&#xff0c;随着人工智能技术的发展&…

MyBatis认识

一、定义 MyBatis是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;Plain Old Java O…

【热门话题】ElementUI 快速入门指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 ElementUI 快速入门指南环境准备安装 ElementUI创建 Vue 项目安装 ElementUI 基…

SpringBoot之远程调用的三大方式

为什么要使用远程调用&#xff1f; SpringBoot不仅继承了Spring框架原有的优秀特性&#xff0c;而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。在Spring-Boot项目开发中&#xff0c;存在着本模块的代码需要访问外面模块接口&#xff0c;或外部url链接的需求…

Golang 开发实战day13 - Reciver Functions

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 Golang 开发实战day13 - 接收…

第42天:WEB攻防-PHP应用MYSQL架构SQL注入跨库查询文件读写权限操作

第四十二天 一、PHP-MYSQL-SQL注入-常规查询 1.PHP-MYSQL-Web组成架构 MySQL(统一管理) ​ root&#xff08;自带默认&#xff09; ​ 网站A testA ​ 网站B testB MySQL(一对一管理) ​ testA用户 ​ 网站A testA ​ testB用户 ​ 网站B testB access无数据库用户 m…

三勾软件 / 三勾点餐系统门店系统,java+springboot+vue3

项目介绍 三勾点餐系统基于javaspringbootelement-plusuniapp打造的面向开发的小程序商城&#xff0c;方便二次开发或直接使用&#xff0c;可发布到多端&#xff0c;包括微信小程序、微信公众号、QQ小程序、支付宝小程序、字节跳动小程序、百度小程序、android端、ios端。 在…

LVS 负载均衡部署 NAT模式

一、环境准备 配置环境&#xff1a; 负载调度器&#xff1a;配置双网卡 内网&#xff1a;172.168.1.11(ens33) 外网卡&#xff1a;12.0.0.1(ens37)二台WEB服务器集群池&#xff1a;172.168.1.12、172.168.1.13 一台NFS共享服务器&#xff1a;172.168.1.14客户端&#xff…