数据 分片

背景

传统的将数据集中存储至单一节点的解决方案,在性能、可用性和运维成本这三方面已经难于满足海量数据的场景。

从性能方面来说,由于关系型数据库大多采用 B+ 树类型的索引,在数据量超过阈值的情况下,索引深度的增加也将使得磁盘访问的 IO 次数增加,进而导致查询性能的下降; 同时,高并发访问请求也使得集中式数据库成为系统的最大瓶颈。

从可用性的方面来讲,服务化的无状态性,能够达到较小成本的随意扩容,这必然导致系统的最终压力都落在数据库之上。 而单一的数据节点,或者简单的主从架构,已经越来越难以承担。数据库的可用性,已成为整个系统的关键。

从运维成本方面考虑,当一个数据库实例中的数据达到阈值以上,对于 DBA 的运维压力就会增大。 数据备份和恢复的时间成本都将随着数据量的大小而愈发不可控。一般来讲,单一数据库实例的数据的阈值在 1TB 之内,是比较合理的范围。

在传统的关系型数据库无法满足互联网场景需要的情况下,将数据存储至原生支持分布式的 NoSQL 的尝试越来越多。 但 NoSQL 对 SQL 的不兼容性以及生态圈的不完善,使得它们在与关系型数据库的博弈中始终无法完成致命一击,而关系型数据库的地位却依然不可撼动。

数据分片指按照某个维度将存放在单一数据库中的数据分散地存放至多个数据库或表中以达到提升性能瓶颈以及可用性的效果。 数据分片的有效手段是对关系型数据库进行分库和分表。分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈。 除此之外,分库还能够用于有效的分散对数据库单点的访问量;分表虽然无法缓解数据库压力,但却能够提供尽量将分布式事务转化为本地事务的可能,一旦涉及到跨库的更新操作,分布式事务往往会使问题变得复杂。 使用多主多从的分片方式,可以有效的避免数据单点,从而提升数据架构的可用性。

通过分库和分表进行数据的拆分来使得各个表的数据量保持在阈值以下,以及对流量进行疏导应对高访问量,是应对高并发和海量数据系统的有效手段。 数据分片的拆分方式又分为垂直分片和水平分片。

垂直分片

按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。 在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。 下图展示了根据业务需要,将用户表和订单表垂直分片到不同的数据库的方案。

垂直分片往往需要对架构和设计进行调整。通常来讲,是来不及应对互联网业务需求快速变化的;而且,它也并无法真正的解决单点瓶颈。 垂直拆分可以缓解数据量和访问量带来的问题,但无法根治。如果垂直拆分之后,表中的数据量依然超过单节点所能承载的阈值,则需要水平分片来进一步处理。

水平分片

水平分片又称为横向拆分。 相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分。 例如:根据主键分片,偶数主键的记录放入 0 库(或表),奇数主键的记录放入 1 库(或表),如下所示。

select * from t_user where id=1

select * from t_user where id=2

水平分片从理论上突破了单机数据量处理的瓶颈,并且扩展相对自由,是数据分片的标准解决方案。

挑战

虽然数据分片解决了性能、可用性以及单点备份恢复等问题,但分布式的架构在获得了收益的同时,也引入了新的问题。

面对如此散乱的分片之后的数据,应用开发工程师和数据库管理员对数据库的操作变得异常繁重就是其中的重要挑战之一。 他们需要知道数据需要从哪个具体的数据库的子表中获取。

另一个挑战则是,能够正确的运行在单节点数据库中的 SQL,在分片之后的数据库中并不一定能够正确运行。 例如,分表导致表名称的修改,或者分页、排序、聚合分组等操作的不正确处理。

跨库事务也是分布式的数据库集群要面对的棘手事情。 合理采用分表,可以在降低单表数据量的情况下,尽量使用本地事务,善于使用同库不同表可有效避免分布式事务带来的麻烦。 在不能避免跨库事务的场景,有些业务仍然需要保持事务的一致性。 而基于 XA 的分布式事务由于在并发度高的场景中性能无法满足需要,并未被互联网巨头大规模使用,他们大多采用最终一致性的柔性事务代替强一致事务。

目标

尽量透明化分库分表所带来的影响,让使用方尽量像使用一个数据库一样使用水平分片之后的数据库集群。

<think>好的,我现在需要帮助用户了解Modbus协议中数据分片的处理方式或实现方法。首先,我需要回忆Modbus协议的基本知识,尤其是关于数据传输的部分。根据用户提供的引用内容,Modbus是一个应用层协议,支持多种物理层,如RS-485和TCP/IP。数据分片通常发生在数据量超过协议规定的最大长度时,这时候需要将数据分割成多个片段传输。 首先,用户提到的引用[2]指出Modbus定义了数据的封装格式和功能码,所以我需要确认Modbus协议本身是否有关于数据分片的规范。根据我的了解,Modbus协议本身并没有内置的分片机制,尤其是在RTU和ASCII模式下,数据帧的长度是有限制的。例如,Modbus RTU的帧最大长度是256字节,包括地址、功能码、数据以及CRC校验。当应用层的数据超过这个限制时,就需要进行分片处理。 接下来,用户的问题是关于如何实现和处理数据分片。我需要分情况讨论不同的Modbus传输模式,比如RTU、ASCII和TCP。在TCP模式下,由于基于以太网,传输层本身可以处理大数据包的分段,但应用层可能仍然需要处理数据分割,尤其是当数据超过Modbus PDU(协议数据单元)的限制时。例如,Modbus TCP的PDU最大长度是253字节,超过的话可能需要分多个请求发送。 然后,需要考虑分片的具体实现方法。例如,在读取保持寄存器时,如果请求的寄存器数量太多,导致响应超过最大帧长度,主站需要将请求分成多个子请求,每个子请求处理一部分寄存器。同样,写入多个寄存器时也需要分片。这里可能需要引用一些功能码,如读保持寄存器(功能码03)和写多个寄存器(功能码16)。 另外,错误处理也是分片实现中需要注意的部分。每个分片请求都需要独立处理,并确保所有分片都成功执行。如果某个分片失败,主站需要重新发送该分片或进行适当的错误恢复。此外,分片后的数据在接收端需要正确重组,确保数据的完整性和顺序。 还需要提到一些优化的方法,比如动态调整分片大小以适应不同的网络条件,或者使用传输层协议(如TCP)的特性来减少分片的次数。不过,在RTU/ASCII模式下,由于没有传输层的分段支持,分片必须完全由应用层处理。 最后,总结Modbus数据分片的关键点,即分片机制不在协议本身,而由应用层实现,需根据传输模式调整策略,并注意错误处理和重组。同时,结合用户提供的引用[3]中关于RS485电平逻辑的内容,可能还需要考虑物理层传输的稳定性对分片数据的影响,确保每个分片在传输过程中不会因信号问题导致错误。</think>### Modbus协议中数据分片处理方式 Modbus协议本身并未定义标准化的数据分片机制,但在实际应用中,当传输数据量超过单帧限制时,需通过**应用层逻辑**实现分片处理。具体实现方法如下: --- #### 1. **分片触发条件** - **RTU/ASCII模式**:单帧最大长度为256字节(含地址、功能码、数据、校验)。若数据域长度超过$L_{max}=256-2=254$字节(去除非数据部分)需分片[^2]。 - **TCP模式**:协议数据单元(PDU)最大为253字节(去除非应用层头部),超过时需分片[^1]。 --- #### 2. **分片实现方法** ##### (1) **读操作分片**(如功能码03读保持寄存器) - **步骤**: 1. 主站计算需读取的寄存器总数$N$,若$N \times 2$(每个寄存器2字节)超过单帧容量,则将$N$拆分为多个子请求。 2. 每个子请求指定起始地址和寄存器数量,确保响应数据长度$\leq L_{max}$。 3. 从站按子请求顺序返回数据,主站重组数据。 - **示例**: ```python def read_registers(start_addr, total_registers, max_per_frame=125): for i in range(0, total_registers, max_per_frame): sub_start = start_addr + i sub_count = min(max_per_frame, total_registers - i) # 发送功能码03请求:地址=sub_start,数量=sub_count # 接收并缓存数据 ``` ##### (2) **写操作分片**(如功能码16写多个寄存器) - **步骤**: 1. 主站将待写入数据按寄存器数量拆分,每个子请求包含连续寄存器块。 2. 每个子请求的写入数量需满足$2 \times N + 9 \leq L_{max}$(RTU模式)[^2]。 3. 从站按顺序执行写入,主站需验证每个子请求的成功状态。 --- #### 3. **分片重组与错误处理** - **数据顺序标识**:在TCP模式下可利用事务标识符(Transaction ID)标记分片顺序[^1];RTU/ASCII模式需依赖应用层序号标记。 - **超时重传**:若某分片未收到响应,主站需重发该分片。 - **完整性校验**:重组后数据需通过业务逻辑校验(如CRC、总和校验等)。 --- #### 4. **分片优化策略** - **动态分片大小**:根据网络质量调整分片长度(如TCP MSS协商)。 - **批量请求合并**:在TCP模式下,使用功能码23(读/写多个寄存器)减少分片次数。 --- #### 5. **物理层影响** RS-485总线中需注意分片间隔时间,若两帧间隔小于3.5字符时间,从站可能误判为同一帧[^3]。建议分片间添加延时: $$ T_{delay} > \frac{3.5 \times (11 \, \text{bit/字符})}{波特率} $$ --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值