网站模板下载百度云链接怎么做的crm管理系统定制
news/
2025/10/4 10:24:08/
文章来源:
网站模板下载百度云链接怎么做的,crm管理系统定制,永年网站建设,porto wordpress汉化版本文由云社区发表本文作者#xff1a;许中清#xff0c;腾讯云自研数据库CynosDB的分布式存储CynosStore负责人。从事数据库内核开发、数据库产品架构和规划。曾就职于华为#xff0c;2015年加入腾讯#xff0c;参与过TBase(PGXZ)、CynosDB等数据库产品研发。专注于关系数据…本文由云社区发表本文作者许中清腾讯云自研数据库CynosDB的分布式存储CynosStore负责人。从事数据库内核开发、数据库产品架构和规划。曾就职于华为2015年加入腾讯参与过TBase(PGXZ)、CynosDB等数据库产品研发。专注于关系数据库、数据库集群、新型数据库架构等领域。目前担任CynosDB的分布式存储CynosStore负责人。企业IT系统迁移到公有云上已然是正在发生的趋势。数据库服务作为公有云上提供的关键组件是企业客户是否愿意将自己运行多年的系统搬到云上的关键考量之一。另一方面自从System R开始关系数据库系统已经大约四十年的历史了。尤其是随着互联网的发展业务对数据库实例的吞吐量要求越来越高。对于很多业务来说单个物理机器所能提供的最大吞吐量已经不能满足业务的高速发展。因此数据库集群是很多IT系统绕不过去的坎。CynosDB for PostgreSQL是腾讯云自研的一款云原生数据库其主要核心思想来自于亚马逊的云数据库服务Aurora。这种核心思想就是“基于日志的存储”和“存储计算分离”。同时CynosDB在架构和工程实现上确实有很多和Aurora不一样的地方。CynosDB相比传统的单机数据库主要解决如下问题存算分离存算分离是云数据库区别于传统数据库的主要特点之一主要是为了1)提升资源利用效率用户用多少资源就给多少资源2)计算节点无状态更有利于数据库服务的高可用性和集群管理(故障恢复、实例迁移)的便利性。存储自动扩缩容传统关系型数据库会受到单个物理机器资源的限制包括单机上存储空间的限制和计算能力的限制。CynosDB采用分布式存储来突破单机存储限制。另外存储支持多副本通过RAFT协议来保证多副本的一致性。更高的网络利用率通过基于日志的存储设计思路大幅度降低数据库运行过程中的网络流量。更高的吞吐量传统的数据库集群面临的一个关键问题是分布式事务和集群吞吐量线性扩展的矛盾。也就是说很多数据库集群要么支持完整的ACID要么追求极好的线性扩展性大部分时候鱼和熊掌不可兼得。前者比如Oracle RAC是目前市场上最成熟最完善的数据库集群提供对业务完全透明的数据访问服务。但是Oracle RAC的线性扩展性却被市场证明还不够因此更多用户主要用RAC来构建高可用集群而不是高扩展的集群。后者比如Proxy开源DB的数据库集群方案通常能提供很好的线性扩展性但是因为不支持分布式事务对数据库用户存在较大的限制。又或者可以支持分布式事务但是当跨节点写入比例很大时反过来降低了线性扩展能力。CynosDB通过采用一写多读的方式利用只读节点的线性扩展来提升整个系统的最大吞吐量对于绝大部份公有云用户来说这就已经足够了。存储自动扩缩容传统关系型数据库会受到单个物理机器资源的限制包括单机上存储空间的限制和计算能力的限制。CynosDB采用分布式存储来突破单机存储限制。另外存储支持多副本通过RAFT协议来保证多副本的一致性。更高的网络利用率通过基于日志的存储设计思路大幅度降低数据库运行过程中的网络流量。更高的吞吐量传统的数据库集群面临的一个关键问题是分布式事务和集群吞吐量线性扩展的矛盾。也就是说很多数据库集群要么支持完整的ACID要么追求极好的线性扩展性大部分时候鱼和熊掌不可兼得。前者比如Oracle RAC是目前市场上最成熟最完善的数据库集群提供对业务完全透明的数据访问服务。但是Oracle RAC的线性扩展性却被市场证明还不够因此更多用户主要用RAC来构建高可用集群而不是高扩展的集群。后者比如Proxy开源DB的数据库集群方案通常能提供很好的线性扩展性但是因为不支持分布式事务对数据库用户存在较大的限制。又或者可以支持分布式事务但是当跨节点写入比例很大时反过来降低了线性扩展能力。CynosDB通过采用一写多读的方式利用只读节点的线性扩展来提升整个系统的最大吞吐量对于绝大部份公有云用户来说这就已经足够了。下图为CynosDB for PostgreSQL的产品架构图CynosDB是一个基于共享存储、支持一写多读的数据库集群。CynosDB for PostgreSQL产品架构图图一CynosDB for PostgreSQL产品架构图CynosDB基于CynosStore之上CynosStore是一个分布式存储为CynosDB提供坚实的底座。CynosStore由多个Store Node和CynosStore Client组成。CynosStore Client以二进制包的形式与DB(PostgreSQL)一起编译为DB提供访问接口以及负责主从DB之间的日志流传输。除此之外每个Store Node会自动将数据和日志持续地备份到腾讯云对象存储服务COS上用来实现PITR(即时恢复)功能。一、CynosStore数据组织形式CynosStore会为每一个数据库分配一段存储空间我们称之为Pool一个数据库对应一个Pool。数据库存储空间的扩缩容是通过Pool的扩缩容来实现的。一个Pool会分成多个Segment Group(SG)每个SG固定大小为10G。我们也把每个SG叫做一个逻辑分片。一个Segment Group(SG)由多个物理的Segment组成一个Segment对应一个物理副本多个副本通过RAFT协议来实现一致性。Segment是CynosStore中最小的数据迁移和备份单位。每个SG保存属于它的数据以及对这部分数据最近一段时间的写日志。CynosStore 数据组织形式图二 CynosStore 数据组织形式图二中CynosStore一共有3个Store NodeCynosStore中创建了一个Pool这个Pool由3个SG组成每个SG有3个副本。CynosStore还有空闲的副本可以用来给当前Pool扩容也可以创建另一个Pool将这空闲的3个Segment组成一个SG并分配个这个新的Pool。二、基于日志异步写的分布式存储传统的数据通常采用WAL(日志先写)来实现事务和故障恢复。这样做最直观的好处是1)数据库down机后可以根据持久化的WAL来恢复数据页。2)先写日志而不是直接写数据可以在数据库写操作的关键路径上将随机IO(写数据页)变成顺序IO(写日志)便于提升数据库性能。基于日志的存储图三 基于日志的存储图三(左)极度抽象地描述了传统数据库写数据的过程每次修改数据的时候必须保证日志先持久化之后才可以对数据页进行持久化。触发日志持久化的时机通常有1)事务提交时这个事务产生的最大日志点之前的所有日志必须持久化之后才能返回给客户端事务提交成功2)当日志缓存空间不够用时必须持久化之后才能释放日志缓存空间3)当数据页缓存空间不够用时必须淘汰部分数据页来释放缓存空间。比如根据淘汰算法必须要淘汰脏页A那么最后修改A的日志点之前的所有日志必须先持久化然后才可以持久化A到存储最后才能真正从数据缓存空间中将A淘汰。从理论上来说数据库只需要持久化日志就可以了。因为只要拥有从数据库初始化时刻到当前的所有日志数据库就能恢复出当前任何一个数据页的内容。也就是说数据库只需要写日志而不需要写数据页就能保证数据的完整性和正确性。但是实际上数据库实现者不会这么做因为1)从头到尾遍历日志恢复出每个数据页将是非常耗时的2)全量日志比数据本身规模要大得多需要更多的磁盘空间去存储。那么如果持久化日志的存储设备不仅仅具有存储能力还拥有计算能力能够自行将日志重放到最新的页的话将会怎么样是的如果这样的话数据库引擎就没有必要将数据页传递给存储了因为存储可以自行计算出新页并持久化。这就是CynosDB“采用基于日志的存储”的核心思想。图三(右)极度抽象地描述了这种思想。图中计算节点和存储节点置于不同的物理机存储节点除了持久化日志以外还具备通过apply日志生成最新数据页面的能力。如此一来计算节点只需要写日志到存储节点即可而不需要再将数据页传递给存储节点。下图描述了采用基于日志存储的CynosStore的结构。基于日志的存储图四 CynosStore基于日志的存储此图描述了数据库引擎如何访问CynosStore。数据库引擎通过CynosStore Client来访问CynosStore。最核心的两个操作包括1)写日志2)读数据页。数据库引擎将数据库日志传递给CynosStoreCynosStore Client负责将数据库日志转换成CynosStore Journal并且负责将这些并发写入的Journal进行序列化最后根据Journal修改的数据页路由到不同的SG上去并发送给SG所属Store Node。另外CynosStore Client采用异步的方式监听各个Store Node的日志持久化确认消息并将归并之后的最新的持久化日志点告诉数据库引擎。当数据库引擎访问的数据页在缓存中不命中时需要向CynosStore读取需要的页(read block)。read block是同步操作。并且CynosStore支持一定时间范围的多版本页读取。因为各个Store Node在重放日志时的步调不能完全做到一致总会有先有后因此需要读请求发起者提供一致性点来保证数据库引擎所要求的一致性或者默认情况下由CynosStore用最新的一致性点(读点)去读数据页。另外在一写多读的场景下只读数据库实例也需要用到CynosStore提供的多版本特性。CynosStore提供两个层面的访问接口一个是块设备层面的接口另一个是基于块设备的文件系统层面的接口。分别叫做CynosBS和CynosFS他们都采用这种异步写日志、同步读数据的接口形式。那么CynosDB for PostgreSQL采用基于日志的存储相比一主多从PostgreSQL集群来说到底能带来哪些好处1)减少网络流量。首先只要存算分离就避免不了计算节点向存储节点发送数据。如果我们还是使用传统数据库网络硬盘的方式来做存算分离(计算和存储介质的分离)那么网络中除了需要传递日志以外还需要传递数据传递数据的大小由并发写入量、数据库缓存大小、以及checkpoint频率来决定。以CynosStore作为底座的CynosDB只需要将日志传递给CynosStore就可以了降低网络流量。2)更加有利于基于共享存储的集群的实现一个数据库的多个实例(一写多读)访问同一个Pool。基于日志写的CynosStore能够保证只要DB主节点(读写节点)写入日志到CynosStore就能让从节点(只读节点)能够读到被这部分日志修改过的数据页最新版本而不需要等待主节点通过checkpoint等操作将数据页持久化到存储才能让读节点见到最新数据页。这样能够大大降低主从数据库实例之间的延时。不然从节点需要等待主节点将数据页持久化之后(checkpoint)才能推进读点。如果这样对于主节点来说checkpoint的间隔太久的话就会导致主从延时加大如果checkpoint间隔太小又会导致主节点写数据的网络流量增大。当然apply日志之后的新数据页的持久化这部分工作总是要做的不会凭空消失只是从数据库引擎下移到了CynosStore。但是正如前文所述除了降低不必要的网络流量以外CynosStore的各个SG是并行来做redo和持久化的。并且一个Pool的SG数量可以按需扩展SG的宿主Store Node可以动态调度因此可以用非常灵活和高效的方式来完成这部分工作。三、CynosStore Journal(CSJ)CynosStore Journal(CSJ)完成类似数据库日志的功能比如PostgreSQL的WAL。CSJ与PostgreSQL WAL不同的地方在于CSJ拥有自己的日志格式与数据库语义解耦合。PostgreSQL WAL只有PostgreSQL引擎可以生成和解析也就是说当其他存储引擎拿到PostgreSQL WAL片段和这部分片段所修改的基础页内容也没有办法恢复出最新的页内容。CSJ致力于定义一种与各种存储引擎逻辑无关的日志格式便于建立一个通用的基于日志的分布式存储系统。CSJ定了5种Journal类型1.SetByte用Journal中的内容覆盖指定数据页中、指定偏移位置、指定长度的连续存储空间。\2. SetBit与SetByte类似不同的是SetBit的最小粒度是Bit例如PostgreSQL中hitbit信息可以转换成SetBit日志。\3. ClearPage当新分配Page时需要将其初始化此时新分配页的原始内容并不重要因此不需要将其从物理设备中读出来而仅仅需要用一个全零页写入即可ClearPage就是描述这种修改的日志类型。\4. DataMove有一些写入操作将页面中一部分的内容移动到另一个地方DataMove类型的日志用来描述这种操作。比如PostgreSQL在Vacuum过程中对Page进行compact操作此时用DataMove比用SetByte日志量更小。\5. UserDefined数据库引擎总会有一些操作并不会修改某个具体的页面内容但是需要存放在日志中。比如PostgreSQL的最新的事务id(xid)就是存储在WAL中便于数据库故障恢复时知道从那个xid开始分配。这种类型日志跟数据库引擎语义相关不需要CynosStore去理解但是又需要日志将其持久化。UserDefined就是来描述这种日志的。CynosStore针对这种日志只负责持久化和提供查询接口apply CSJ时会忽略它。以上5种类型的Journal是存储最底层的日志只要对数据的写是基于块/页的都可以转换成这5种日志来描述。当然也有一些引擎不太适合转换成这种最底层的日志格式比如基于LSM的存储引擎。CSJ的另一个特点是乱序持久化因为一个Pool的CSJ会路由到多个SG上并且采用异步写入的方式。而每个SG返回的journal ack并不同步并且相互穿插因此CynosStore Client还需要将这些ack进行归并并推进连续CSJ点(VDL)。 CynosStore日志路由和乱序ACK图五 CynosStore日志路由和乱序ACK只要是连续日志根据数据分片路由就会有日志乱序ack的问题从而必须对日志ack进行归并。Aurora有这个机制CynosDB同样有。为了便于理解我们对Journal中的各个关键点的命名采用跟Aurora同样的方式。这里需要重点描述的是MTRMTR是CynosStore提供的原子写单位CSJ就是由一个MTR紧挨着一个MTR组成的任意一个日志必须属于一个MTR一个MTR中的多条日志很有可能属于不同的SG。针对PostgreSQL引擎可以近似理解为一个XLogRecord对应一个MTR一个数据库事务的日志由一个或者多个MTR组成多个数据库并发事务的MTR可以相互穿插。但是CynosStore并不理解和感知数据库引擎的事务逻辑而只理解MTR。发送给CynosStore的读请求所提供的读点必须不能在一个MTR的内部某个日志点。简而言之MTR就是CynosStore的事务。四、故障恢复当主实例发生故障后有可能这个主实例上Pool中各个SG持久化的日志点在全局范围内并不连续或者说有空洞。而这些空洞所对应的日志内容已经无从得知。比如有3条连续的日志j1, j2, j3分别路由到三个SG上分别为sg1, sg2, sg3。在发生故障的那一刻j1和j3已经成功发送到sg1和sg3。但是j2还在CynosStore Client所在机器的网络缓冲区中并且随着主实例故障而丢失。那么当新的主实例启动后这个Pool上就会有不连续的日志j1, j3而j2已经丢失。当这种故障场景发生后新启动的主实例将会根据上次持久化的连续日志VDL在每个SG上查询自从这个VDL之后的所有日志并将这些日志进行归并计算出新的连续持久化的日志号VDL。这就是新的一致性点。新实例通过CynosStore提供的Truncate接口将每个SG上大于VDL的日志truncate掉那么新实例产生的第一条journal将从这个新的VDL的下一条开始。故障恢复时日志恢复过程图六故障恢复时日志恢复过程如果图五刚好是某个数据库实例故障发生的时间点当重新启动一个数据库读写实例之后图六就是计算新的一致性点的过程。CynosStore Client会计算得出新的一致性点就是8并且把大于8的日志都Truncate掉。也就是把SG2上的9和10truncate掉。下一个产生的日志将会从9开始。五、多副本一致性CynosStore采用Multi-RAFT来实现SG的多副本一致性 CynosStore采用批量和异步流水线的方式来提升RAFT的吞吐量。我们采用CynosStore自定义的benchmark测得单个SG上日志持久化的吞吐量为375万条/每秒。CynosStore benchmark采用异步写入日志的方式测试CynosStore的吞吐量日志类型包含SetByte和SetBit两种写日志线程持续不断地写入日志监听线程负责处理ack回包并推进VDL然后benchmark测量单位时间内VDL的推进速度。375万条/秒意味着每秒钟一个SG持久化375万条SetByte和SetBit日志。在一个SG的场景下CynosStore Client到Store Node的平均网络流量171MB/每秒这也是一个Leader到一个Follower的网络流量。六、一写多读CynosDB基于共享存储CynosStore提供对同一个Pool上的一写多读数据库实例的支持以提升数据库的吞吐量。基于共享存储的一写多读需要解决两个问题\1. 主节点(读写节点)如何将对页的修改通知给从节点(只读节点)。因为从节点也是有Buffer的当从节点缓存的页面在主节点中被修改时从节点需要一种机制来得知这个被修改的消息从而在从节点Buffer中更新这个修改或者从CynosStore中重读这个页的新版本。\2. 从节点上的读请求如何读到数据库的一致性的快照。开源PostgreSQL的主备模式中备机通过利用主机同步过来的快照信息和事务信息构造一个快照(活动事务列表)。CynosDB的从节点除了需要数据库快照(活动事务列表)以外还需要一个CynosStore的快照(一致性读点)。因为分片的日志时并行apply的。如果一个一写多读的共享存储数据库集群的存储本身不具备日志重做的能力主从内存页的同步有两种备选方案第一种备选方案主从之间只同步日志。从实例将至少需要保留主实例自从上次checkpoint以来所有产生的日志一旦从实例产生cache miss只能从存储上读取上次checkpoint的base页并在此基础上重放日志缓存中自上次checkpoint以来的所有关于这个页的修改。这种方法的关键问题在于如果主实例checkpoint之间的时间间隔太长或者日志量太大会导致从实例在命中率不高的情况下在apply日志上耗费非常多的时间。甚至极端场景下导致从实例对同一个页会反复多次apply同一段日志除了大幅增大查询时延还产生了很多没必要的CPU开销同时也会导致主从之间的延时有可能大幅增加。第二种备选方案主实例向从实例提供读取内存缓冲区数据页的服务主实例定期将被修改的页号和日志同步给从实例。当读页时从实例首先根据主实例同步的被修改的页号信息来判断是1)直接使用从实例自己的内存页还是2)根据内存页和日志重放新的内存页还是3)从主实例拉取最新的内存页还是4)从存储读取页。这种方法有点类似Oracle RAC的简化版。这种方案要解决两个关键问题1)不同的从实例从主实例获取的页可能是不同版本主实例内存页服务有可能需要提供多版本的能力。2)读内存页服务可能对主实例产生较大负担因为除了多个从实例的影响以外还有一点就是每次主实例中的某个页哪怕修改很小的一部分内容从实例如果读到此页则必须拉取整页内容。大致来说主实例修改越频繁从实例拉取也会更频繁。相比较来说CynosStore也需要同步脏页但是CynosStore的从实例获取新页的方式要灵活的多有两种选择1)从日志重放内存页2)从StoreNode读取。从实例对同步脏页需要的最小信息仅仅是到底哪些页被主实例给修改过主从同步日志内容是为了让从实例加速以及降低Store Node的负担。CynosDB一写多读图七 CynosDB一写多读图七描述了一写一读(一主一从)的基本框架一写多读(一主多从)就是一写一读的叠加。CynosStore Client(CSClient)运行态区分主从主CSClient源源不断地将CynosStore Journal(CSJ)从主实例发送到从实例与开源PostgreSQL主备模式不同的是只要这些连续的日志到达从实例不用等到这些日志全部applyDB engine就可以读到这些日志所修改的最新版本。从而降低主从之间的时延。这里体现“基于日志的存储”的优势只要主实例将日志持久化到Store Node从实例即可读到这些日志所修改的最新版本数据页。七、结语CynosStore是一个完全从零打造、适应云数据库的分布式存储。CynosStore在架构上具备一些天然优势1)存储计算分离并且把存储计算的网络流量降到最低 2)提升资源利用率降低云成本3)更加有利于数据库实例实现一写多读4)相比一主两从的传统RDS集群具备更高的性能。除此之外后续我们会在性能、高可用、资源隔离等方面对CynosStore进行进一步的增强。此文已由作者授权腾讯云社区发布
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/927015.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!