从传统数据库痛点看分布式数据库选型问题

news2024/11/15 9:47:41

本文转载自:OceanBase 社区

作者简介:蔡鹏,拥有十多年DBA工作经历,曾就职于饿了么、蚂蚁集团,现任货拉拉数据库部门负责人,负责数据库、缓存,消息队列的管理与平台研发工作。

引言

近年来,随着互联网大厂掀起分布式数据库的技术浪潮,中小型互联网企业也在不同业务场景下纷纷试水分布式数据库,电信、金融、银行、保险等传统领域的大型企业也逐渐转向分布式数据库,这也成为DBA这个小圈子中热议的话题。 确实,从现实需求上看,各行各行业的数据量与日俱增,在这样的背景下,我们需要“随波逐流”布局分布式数据库吗?以下为个人浅显的思考,供大家简单参考、水平有限如有错误烦请指正。

传统数据库痛点

说起分布式数据库,必须先提一下传统单机数据库。以大家较为熟悉的MySQL为例,传统单机数据库架构简单,由若干台节点通过Binlog复制构成一个集群,写集中在主库,读则分摊在集群的各个节点上。

不可否认的是,上述架构在一些重要特性上存在“天花板较低”的问题,如以下5个特性。

特性1:高可用问题。

MySQL本身是不具备高可用能力的,它的高可用能力通过外部工具协助达成(MySQL高可用方案随着复制的改进有漫长的演化历史)。众所周知,高可用工具往往只能最大限度解决数据一致性的问题,而不能解决HA切换后应用访问的问题,通常一个完整的高可用系统是要HA工具+Proxy联动+ClientDriver连接池合理配置共同实现的。遗憾的是,时至今日不少中小公司并没有丝滑解决HA切换的问题,主要原因是HA工具+Proxy深度定制能力欠缺,篇幅原因不做展开。

特性2:数据一致性问题。

数据复制是存在时差的,造成读一致性问题,但这通常不是太大的问题,通过Proxy bindmaster操作都能解决,不过,master压力可能会同样面临性能瓶颈。

特性3:容量、性能扩展、结构变更。

这是传统单机数据库的三宗罪。存储的扩展在一定程度内可以通过堆硬件(垂直扩容)的方式来解决,但堆硬件也是有限度的,出于可运维、易运维的角度,通常DBA都不会让单实例或者单表太大。可能对于一个冷的日志表存储超过1TB DBA可能就会比较紧张了,毕竟DDL一次可能要以天计算,而对于一个读写高频的订单表超过500GB,估计DBA维护就会如履薄冰瑟瑟发抖了!这时棘手的问题就来了:给够你硬件你都不敢用。

通过堆硬件能在一定程度上缓解存储容量上限的问题,但性能问题是无法靠堆硬件完全解决的。还以订单表为例,如果是日订单百万甚至千万级别,无论怎么折腾单表都会出现严重的读写性能问题,此时通过扩容硬件的方式不能解决问题。一方面是因为数据库本身会由于热点表的高频读写造成严重的锁放大问题,另一方面数据库本身并不能充分使用硬件资源,尤其MySQL 5.6之前的版本由于诸多子线程未从Master主程上拆分,造成CPU使用不充分,这在MySQL 5.7版本后有了很大的改观。尽管如此,还是会受到网卡、磁盘IOPS上限因素的影响,注定单机构成的数据库集群存在性能上限。因此不幸的是:给你足够的资源你都用不到。

不敢用、用不到都很痛苦!为此就诞生了“拆”的想法,根据不同的“拆”法诞生了不同形态的分布式数据库。值得一提的是今天做数据库拆分的初衷并不是为了解决性能瓶颈而是数据存储达到单机上限,更直白一点地说,拆的关键是解决大表运维困境。

特性4HTAP

新时代赋予数据处理新的诉求,目前解决方案还是通过数据流(ETL)的方式将数据写到其他分析型数据库中。不管是链路维护复杂性还是应用健壮性(低延迟、高稳定性)都有不小的麻烦。因此,希望能通过一套数据库搞定所有问题。

特性5:容灾能力。

近几年企业对容灾的要求越来越高,作为DBA也应当确保极端情况下(机房限电、被炸等)数据库具备逃逸能力。单机数据库通过主从(异地部署)方式也能实现,虽然维护较为复杂但也能用。

分布式数据库形态划分

分布式数据库根据不同“拆”法或者设计理念大致有如下三种形态划分。

1、分布式中间件

典型的架构图(简化图),核心思想是通过中间件将多个独立的物理集群组联合起来构成一个逻辑集群,通过某种数据路由规则将用户请求打散到不同节点上。

该做法俗称分库分表,是绝大部分互联网公司在解决容量、性能扩展性问题上的首选方案。该方案将数据基于某种规则(sharding key)均匀拆分到多个集群中来达到分摊存储与计算性能压力,代表的中间件产品TDDL/Cobar/Vitess,及基于该思想诞生的“分布式DB”代表产品TDSQL、StarDB等。这类方案虽然解决了容量、性能可扩展的问题,但是也存在如下的一些问题。

问题1:技术复杂。

通常是大公司专属玩法,普遍基于业务场景做了深度定制,周边有一套完整的配套管控系统支持。目前市面上虽然有一些开源的Proxy也能用,但对于中小公司来说很难从根上可控,使用过程中的棘手问题几乎很难在短时间解决,而且开源产品为了通用性要想基于公司场景化定制有难度。因此,很多中小公司虽然做了分库分表但或多或少存在这样那样的问题。

问题2:对业务有侵入。

从单表到分库分表的改造普遍要求带sharding key作为数据拆分及路由依据,这样业务逻辑被迫进行改造,比如对多表join的场景很难通过中间件去解决、非sharding key的查询被迫要扫片性能则非常低、排序/分页/聚合计算问题,等等。为了解决数据拆后聚合的问题,通常要在整个业务链路上部署复杂的中间件,这给稳定性维护及业务健壮性带来一些挑战。

问题3:扩缩容复杂。

通常在决定分库分表的时候需要提前做好容量评估,分片数定义好后就不在改变,非常不推荐后期再去扩展/缩容分片数。调整(reshard)分片数涉及数据rebalance整个过程。为了保证数据一致性要做很多额外工作,通常是DBA定制开发一个平滑迁移工具,或者研发双写+增量Binlog数据订阅做数据同步。如果reshard操作能内置到中间件,那对研发及DBA来说自然更友好,但目前市面上开源的中间件几乎没有见到有类似的功能!诸如TDSQL、StarDB等从公开资料上看是具备对用户透明的reshard能力的。

问题4:分布式事务问题。

出于对ACID完整性支持的考虑,由中间件形态构成的分布式数据库中解决分布式事务问题,通常解决方案都是差不多的,即两阶段提交(2PC)。

但实现过程非常复杂,也不可避免的对性能造成影响,通常在该形态的分布式数据库中都不太推荐用分布式事务。此外,这里分布式事务不能保证数据一致性或者说对集群而言本质还是最终一致性,该形态的分布式数据库在分布式事务实现上普遍类似,可以参考分布式中间件Seata的实现原理。

对于中小公司可行的做法是业务场景拆分得足够简单的情况下基于代理中间件+业务数据补偿来保证数据的最终一致性,使用分布式框架如Seata也是可行的,但太重了,对性能也会有明显的影响。

问题5:运维复杂性。

分布式中间件形态的数据库往往都有非常完善配套的管控系统来打包解决常见的运维问题,如果公司是基于某个开源的代理中间件做的,则不可避免的也要开发相关的管控系统来统一解决诸如DDL、研发数据订正等问题。整体上还是能很好解决存储、计算能力不足等问题和大表运维困境,只是对业务会有入侵,大公司专属定制,中小公司勉强也能玩转。

问题6:HTAP。

目前看到的分布式中间件形态的数据库基本不具备OLAP的能力,普遍做法还是要将数据流向到分析型数据库中。

问题7:容灾能力。

跟单机主从无本质区别

2、存储计算分离

该形态的分布式数据库核心思想是计算、存储分离,计算与存储解耦,将有状态的数据和日志下推到分布式存储,多个无状态计算节点共享一份数据,代表产品AWS Aurora、阿里PolarDB。

这里简单看一下Aurora对性能、容量、结构变更上的优化。

首先在性能上,the log(redolog) is the database,简单说Aurora没有直接存储MySQL的innodb page数据页,只有一份redolog日志(个人理解应该是区别于innodb的wal,最多是概念的相似,没有做深度考证),当需要读取数据时将redolog转换为data page。这样设计由于只存储了一份redo数据(批量+顺序I/O)无需写data page因此也不存在缓冲区刷脏跟随机I/O写的问题,这相比于MySQL写I/O放大要精简很多,因此性能要提升很多。引用公开资料结论:事务I/O开销只有MySQL 1/7事务处理能力是MySQL的35倍。

不过有利就有弊,Aurora Server层还是原汁原味的MySQL Server(100%兼容原生MySQL),读取数据时不可能直接读取redolog,需要将redolog转换为data page,转换是要支付CPU代价的。当然基于该特殊设计还有一些其他比较好用的功能如秒级备份(俗称拍快照),就不多介绍了。

其次在容量上,存储构建在S3共享存储之上,对于容量扩展可以支撑足够大的数据量(64TB),多个副本之间通过Gossip协议保障数据一致性的,得益于S3的设计副本间的数据同步是非常高效的,因此副本间的数据延迟非常低。笔者在写该文档时顺便查了一下当天的副本延迟监控P90居然都不到1s,对比原生MySQL即使是优化后的GroupCommit+MTS也很难做到这一点。

值得一提的是,正是基于log is data的设计+S3 log同步避免了多数据副本间为数据一致性采取的2PC/3PC提交或者更复杂的Paxos算法,非常niubility的设计。最后Aurora的存储容量是弹性伸缩的,DBA无需主动扩容,不过从使用经验上看,在业务释放空间后似乎并没有做“缩”的动作,会继续按照此前实例使用的最大存储来计费(略坑),这点目前不清楚具体原因是啥!

在结构变更方面,目前跟原生MySQL一样也是fast ddl,在lab mode(实验室模式默认关闭状态,官方不推荐用……)支持Instant ddl,不过只针对add column操作,目前DDL操作其实还是以pt-osc/gh-ost为主。虽然大表容量的问题解决了但对于超大表的运维还会存在一定的问题。即使通过pt-osc/gh-ost能丝滑变更,以及MySQL没有明确规定单表大小及行数上限,但出于b-tree的原因在行数过多后还是会影响到读写性能,笔者在实际使用过程中就出现了一张400G的单表DDL超过12小时的情况,为此发布系统不得不block这个表的发布长达一年的时间。存储计算分离的形态下,尽管架构是分布式的,在具体的设计思想上也非常先进,但对于解决大表问题还是稍稍有一点小遗憾,不过相比传统单机数据库已经不用担心容量问题了,这一点对于业务体量不大既不想用中间件也不想对业务动刀的公司而言似乎也是不错的选择,况且SQL协议100%兼容。

此外,通过将计算下推到分布式存储的多个存储单元上实现并行查询从而具备一定的分析能力,也很难满足分析型场景要求。不过,存储计算分离的形态天然具备同城+异地容灾能力。

在使用Aurora的使用体感上,笔者更倾向于把它当作一个不宕机的容量性能无限扩展的单机数据库来使用,当业务体量到一定程度后出于易维护的角度考虑,最后大概率还是要拆的。最后建议如果中间件能力缺乏又不想因拆导致的后续一堆麻烦的问题,即使维护麻烦一点也可以继续使用。

PolarDB与Aurora类似,也采用了存储计算分离架构,因此也能很好解决容量、性能问题,同时也做到100%的协议兼容与较低的数据延迟,至于谁优谁劣,由于二者设计理念不同,以及个人水平有限,不做过多评价跟分析。

PolarDB在比较关心的大表解决方案上做了优化增强,主要解决方法就是通过分区表,如分区键跟主键/唯一键解耦(MySQL则要求pk/uk必须包含分区键),分区锁支持将锁从表粒度降低到分区粒度显著增强并行能力。不过分区能力的增强仍旧不能避免大表下btree局限问题。为此,PolarDB又将btree改成Blink-Tree(没有深入了解,简单说就是通过对节点添加额外字段实现tree调整时全局加锁到部分加锁,进而提高并发度)。同时对于大表DDL问题,PolarDB除支持instant ddl能力外还通过并行DDL能力充分利用存储I/O能力加速DDL进度。

即便有上述优化手段也不能彻底解决大表问题,笔者觉得(纯粹个人理解)基于上述优化后应该是比Aurora裸大表的方式要好一些,起码会大程度上推迟性能瓶颈的到来,这又进一步了推迟了用户分库分表的紧迫性。

关于btree访问的优化,笔者此前还了解到GreatSQL(万里数据库)将B+树划分为若干子树,通过多个线程并行扫描同一张InnoDB表的不同部分,之后在将子线程结果汇总达到提升查询性能的目的,也是一个很机智的设计。

至于HTAP能力,似乎PolarDB有着更大的理想,其内置了X-Engine OLAP分析引擎

这种一款数据库同时内置TP(btree&row存e)+AP(lsm-tree&列存)两个引擎(两份数据),的方案,即数据通过日志的方式在各个引擎间同步,在近两年也逐渐涌现出来(将离线ETL过程给包了),可以想象其在成本、复杂度上该有多高,注定了专属于顶级大厂的玩具,水平有限下文无法分解!

3、原生分布式

代表产品OceanBase、TiDB,该形态数据库通过天然的多副本设计+Paxos/Raft分布式选举协议实现分布式。

在高可用、数据一致性上基于Paxos协议实现,无需外部任何三方工具依赖数据具备强一致性,这一点跟存储计算分离实现高可用也略有不同。

在解决容量、性能问题上自不必说,OceanBase同样具备良好的弹性扩展能力

容灾能力同样也比较灵活,能满足不同等级的容灾要求。

只需要添加节点即可完成容灾建设,操作过程也比较简单,当然其他形态的分布式数据库一样可以做到。

值得一提的是OceanBase具备租户的概念,且租户间资源是隔离的,这一点是有别于目前市场上绝大部分分布式数据库的。基于租户这个特性能玩的花样就多了,如对绝大部分公司而言大部分DB其实都不会面临容量、性能上的问题,这些小DB又有存在的理由,通常我们还不能将它堆到一个集群里,因为无法解决隔离问题,这里多租户就派上用场了。

这里集群租户间资源共享还是隔离是可以灵活设置的,一般有cpu share(共享)、cpu set(独占)两种方式,可以基于场景设置,以实现业务的错峰部署,最大化提高资源利用率。同时,租户的出现可以让DBA在提高资源利用率上具备更灵活的调度策略,如可以开发资源调度系统动态调配不同租户在不同时间的规格配置。这里资源隔离一定要是物理隔离的,如果租户是逻辑隔离意义就小很多。

OceanBase采用了LSM Tree的存储方式,为了避免写放大等性能问题,OceanBase的理念也很简单:能通过硬件解决的问题都不是问题。这让我们看到了单OBServer居然有恐怖的700G内存,这足以容纳绝大部分业务12小时的变更量了,因此,读写尽量在内存中完成,待到低峰期在悄悄完成Compaction。其他都挺好的就是贵!^_^......,

不过在硬件越来越便宜的今天,以及OceanBase 4.0开始小型化、单机化,使得OceanBase也能飞入寻常百姓家了。

在大表的维护上,OceanBase类似PolarDB也是通过分区表的方式来解决,同样可以将分区分布到其他OBServer,只是不清楚是否也做了PolarDB在分区上的诸多优化。所以想当然的会认为OceanBase也存在大表下性能问题和变更问题。不过,OceanBase并不担心大表DDL的问题,原因是得益于上述那个昂贵的设计(OceanBase本身也是维护了schema version的对于大部分DDL同城都是online的),通过低峰期发起Major freeze操作合并完成DDL自然也就完成了。同时为避免合并带来的影响,OceanBase通过多个Zone间轮转合并避免对用户造成影响。不过OceanBase2.0开始在创建索引时就不用等到合并后生效了,用户创建索引就发起索引构建流程缩短生效时间。

关于OceanBase兼容性,它同时兼容Oracle跟MySQL的。OceanBase并不是像Aurora那样接近原汁原味的MySQL Server对MySQL兼容,而是协议层的兼容(小插曲:据说为了跟原汁原味的MySQL表现一致就连Bug都一起兼容了)。从笔者当初使用OceanBase的经验上看,对MySQL的兼容度也比较完整,值得一提的是从MySQL迁移到OceanBase存储规模下降了2/3。

关于HTAP可以参考此前OceanBase CTO的一篇相关文章《真正的HTAP对用户和开发者意味着什么》,引用里面的一个重要观点:

真正的 HTAP 系统有一个要求是基于”一份数据”同时做好交易和分析。那么,什么叫做“一份数据”?想要回答这个问题,核心是要回答哪一种做法是对用户最友好且性价比更高。我认为,数据的多个副本或者多种形态(列索引/ BTree 索引/ Bitmap 索引等)都可以被认为是”一份数据”,前提是能够在满足 HTAP 处理需求的前提下最大程度降低数据冗余。例如,OceanBase 往往存储多个副本( 3 个副本/ 5 个副本),可以选择让其中一个备副本专门做 OLAP 查询;Oracle IMC 支持对表格在内存中建立列索引,SQL Server 支持对表格在磁盘/内存中建立列索引,从用户的角度仍然是“一个系统,一份数据”。

从这里似乎可以窥探到OceanBase关于HTAP的一些设计思想点:一个系统,一份数据,多副本行列混合存,不搭积木。不过由于资料比较少也没有从OceanBase的架构上看到HTAP是怎么体现的,当然肯定有别于以PolarDB为代表的“多份数据”方案。多份数据实现上可能很复杂但OceanBase选择的道路似乎也并不简单甚至更复杂!

我们再从TiDB架构图上看(如下图),对比之下,OceanBase似乎更加简洁一点,起码组件没那么多(部署不够友好)不过这似乎也不是什么大的问题,况且TiDB提供了简洁的部署方案,不得不说TiDB真的很聪明特别懂用户心思,不管是对一个简单的部署,还是一开始选择基于MySQL协议去研发,又或者是围绕MySQL生态打造的各种工具等等都深得用户心意,这一点跟极力试图通过技术证明自己牛逼的产品,走的是不同路子。

对于性能、容量扩展性问题,TiDB同样不逊色,其他分布式数据库也具备良好弹性能力,至于兼容性本身就是基于MySQL协议打造且在一些互联网公司也都验证过了。当然在一些场合下会拿各个数据库进行性能比较,先不说比较的基准是否一致,性能肯定不是选型的第一考虑因素,毕竟性能是可以通过资源去弥补的,因此性能可扩展性非常重要,如最开始提到的:给够资源用不到那分布式就没有意义。稳定性应该更重要,这一点OceanBase在自身大规模金融支付场景下得到过验证这一点是具备足够的说服力的。

关于HTAP,TiDB通过内置TiFlash引擎来实现类似PolarDB的X-Engine做法跟OceanBase的“一份数据”理念似乎还是有点不一样的,太复杂看不清楚。也很难说谁优谁劣只能交给时间跟市场去检验了。

在TiDB6.0里面有多租户概念、虽然也实现了物理隔离,跟OceanBase基于内核虚拟化技术不同的是,TiDB是通过资源打标+调度的方式来实现的,个人觉得OceanBase在这方面要更胜一筹,分布式数据库下租户应该成为一种标配能力,一方面对私有云部署维护管理更加友好,另外对用户而言分布式就是一个无限大的单机数据库不用担心容量跟性能问题,且资源是隔离的。

使用了分布式就可以一劳永逸地解决性能、容量问题了?其实不然,该做的数据拆分跟业务架构改造还是要继续做的,主要还是取决于你的业务体量到底有多大。蚂蚁的交易支付系统体量足够大吧,也没有把所有数据都放到一套OceanBase集群里啊,同样也是将业务拆分(蚂蚁的单元化架构)到多集群的(俗称百库百表)。当然这是个极端的例子,如果对一个百万订单的系统那兴许就不用了,或者更低一点的业务量还要啥分布式啊,单机数据库就挺好的。

对比总结

通过对三种形态的分布式数据库对比,针对可用性、一致性、容量、性能、维护、容灾、HTAP的支持上做了一下简单总结,毕竟不管什么类型的数据库最终还是要回归到数据库的本质。需要说明的是下表不具有选型倾向性,只是理念的不同带来风格的迥异并无高下之分!!!

数据库基本要求

使用友好性

扩展要求

可用性

一致性

扩展能力

容灾能力

业务侵入性

可维护性

普适性

HTAP支持

租户

分布式中间件

弱一致性

复杂

高侵入

简单

适合中小厂

存储计算分离

强一致性

简单

无侵入

复杂

大厂专属

原生分布式

强一致性

简单

无侵入

复杂

大厂专属

OB更优

中间件方案是历史的产物也有它存在的道理,长期看一定会被淘汰,只是周期会比较久(可能分布式数据库云化能加速升级进度),短期内仍旧是中小互联网公司的首选方案,毕竟相对简单一些。

也没有万能的数据库,上面介绍的分布式数据库还是以解决OLTP为主的,并不适合解决所有场景需求,比如json、图、kv、cache、schemaless、dt等场景的需要还是要使用特定类型的数据库。

选型技术之外的考量因素

即使通过上述简单的对比,选择依据似乎还不够。还要从如下几个方面进行考虑。

1. 成熟度。

一款数据库成熟度怎么样可以从历史版本发布情况来简单分析,如果频繁的大版本发布及小版本修复各种致命bug、缺陷等,显然不能被一般外部用户接受。以MySQL为例,2005 年 MySQL 5.0发布到今天MySQL 8.0成熟经历了17年,其中MySQL 8.0从2016年发布到今天一个版本的稳定打磨就经历了7年!数据库注定是要十年磨一剑的。

2. 标杆应用。

在业内是否被大规模验证过了,或者有标志性的成功案例。很多国产数据库目前整体还是闭塞的虽然号称在金融、电信、银行、保险等领域上线了,但实际情况怎么样完全不得而知,尤其互联网公司崇尚的是开源这一类的数据库很难被接受。

3. 技术底蕴&靠山

所谓大厂出品必属精品,随便一个什么公司搞一个数据库是很难被接受的。大家普遍认可业内顶尖的一流公司做背书的产品,甚至在深入了解一下开发这款数据库的团队靠谱吗?毕竟数据库的复杂度堪比操作系统,要求非常高,甚至团队规模怎么样,不要指望百十人的团队能写出靠谱的数据库(KPI产品例外)。当然中间件方案的分布式例外,毕竟核心是做Proxy,复杂度远不在一个数量级上。

4. 生态。

生态主要看技术、人才、文档、服务这四方面。

技术方面,业务接入的改造是否低成本,或者说是否能复用成熟的生态(比如TiDB和OceanBase都是完整支持MySQL协议的),是否足够开放让社区或者相关从业人员尽可能参与进来?比如TiDB这方面做的就很好。周边生态工具是否齐全,比如业务研发高频使用的IDE工具,DBA更加关心的一些技术接口或者现成的实用运维工具等。

人才方面,市场是否有足够数量的从业人员如DBA。

文档方面,此前国产数据库整体上文档完整性比较弱,现在好很多了,不过整体文档水平跟MySQL这样的开文档比还有差距,很明显的感受是:告诉你怎么用,很少告诉你为什么或者原理性的东西比较少,可能是写文档的同学不是内核研发。

服务方面,国产数据库的诞生有现实的需求,但整体相比传统商业数据库成熟度还不够,因此需要更好的售后服务及支撑体系才能弥补整体的不足。分布式数据库未来上云是个大方向,毕竟对绝大部公司而言是很难有人力跟能力去驾驭一个复杂的、成熟度有待打磨的产品。

5. ROI

主要看引入分布式要解决什么问题,如果是成本,很不幸小范围引入分布式数据库可能成本会更高!毕竟相比单机数据库,分布式数据库普遍对硬件成本要求非常高,比如TiDB和OceanBase都有很高的硬件要求(OceanBase4.0小型化后改观很多)。如果是性能优化那更不幸,通常benchmark可能跑不过单机数据库!分布式数据库的整体收益只能在达到一定规模后才能发挥出成本、性能优势。因此,如果只是某个单一场景引入分布式来解决可能不是太好的选择。据说携程是做了大规模MySQ/Oracle升级OceanBase,相信他们应该有相关的数据可供参考。

关于ROI可以简单的比喻:分布式是卡车,拉的多跑的慢,单机数据库是轿车拉的少跑的快,因此要有个平衡。最后引用一句话:“过早的优化是万恶之源”。

6. 兼容性验证

虽然很多数据库都号称100%兼容MySQL等协议,但还是要以自己的实际验证结果为准(99.99%的兼容跟100%的兼容对结果的影响是巨大的)。起码你要有SQL流量回放能力来验证执行计划跟执行效率的差异吧。此外,对于能否平滑迁移,成熟的产品往往有一套完整的解决方案,要考虑上线后你真的能驾驭它吗。


最后的最后,也在最初的最初,我们要考虑的是:真的需要分布式数据库吗?

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

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

相关文章

反诈老陈自曝2022年收入133万

我是卢松松,点点上面的头像,欢迎关注我哦! 反诈老陈自曝2022年收入133万,“缴税近40万,捐赠84万”,曾称网络上得到的收入分文不取。老陈自曝引起了广泛热议。 100万的打赏让老陈离职做直播 相较于普通人…

统计学基础:置信区间和p值知识

引言小伙伴们,今天我们要来聊聊置信区间和p值这两个看起来超级相关的概念。咱们先来说说置信区间,它是一种区间估计,相当于给你的样本数据画了一个“框框”,告诉你总体数据的真实值很可能在这个框框里。就好像你买了一个锅&#x…

CS:GO头号特训添加bot + CS:GO控制台指令大全

CS:GO头号特训添加bot CS:GO控制台指令大全 我是艾西,在我们玩csgo时总是会有一些自己的下想法以及想和小伙伴们一起玩的快乐,今天我跟大家简单的说一下头号特训 头号特训模式下单人或多人跑图的相关指令,帮助玩家熟悉头号特训的玩法、特殊道…

写作利器之Markdown编辑套装

简述 作为一名习惯使用Markdown写作的重度用户,并且经常有发布文章需求的作者来说,一套完善的写作发布套装就显得的很重要了。 所以就有了以下的使用体验,本文大概能解决的问题: 1.由于网络问题或编辑器原因部分网站粘贴后的mar…

Docker【基本使用】

1:启动Docker1.1:操作systemctl start docker.service1.2:常见问题【第一步】启动docker,提示启动失败,查询运行状态systemctl start docker.service【第二步】查询docker运行状态,提示不支持SELinux【第三…

大数据flink框架入门分享(起源与发展、实时与离线计算、场景、处理流程、相关概念、特性普及、入门Demo)

文章目录起源与发展flink在github上的现状实时计算VS离线计算实时计算离线计算实时计算常用的场景框架流处理流程flink电商场景下的业务图示例flink中一些重要特性有界数据和无界数据时间语义、水位线事件时间处理时间水位线flink窗口概念理想中的数据处理含有延迟数据的数据处…

基于BP神经网络的手部动作分类识别,BP神经网络详细原理

目标 背影 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 数据 神经网络参数 基于BP神经网络手部动作识别的MATLAB代码 效果图 结果分析 展望 背影 随着人工智能的发展,智…

深入剖析 MVC 模式与三层架构

文章目录1. 前言2. MVC模式3. 三层架构4. MVC和三层架构5. 总结5.1 IDEA 小技巧1. 前言 前面我们探讨了 JSP 的使用,随着计算机技术的不断更新迭代,JSP 的技术由于存在很多的缺点,已经逐渐退出了历史的舞台,所以在学习时&#xf…

加密功能实现

文章目录1. 前言2. 密码加密1. 前言 本文 主要实现 对密码进行加密 ,因为 使用 md5 容易被穷举 (彩虹表) 而破解 ,使用 spring security 框架又太大了 (杀鸡用牛刀) 。   所以本文 就自己实现一个密码加密 . 2. 密码加密 这里我们通过 加盐是方式 来 对…

pytorch安装的超级详细教程(没有之一)

一、发展历程 (简单介绍) (15年)caffe --> (16年)tensorflow1.x --> (17年)keras --> (18年)Tensorflow2.x --> (19年)pytorch。 面向gihub开源项目编程。 向下支持比较好,各个版本之间支持比较好,兼容性强。 版本…

Android事件拦截(3)——系统拦截和应用拦截

本文主要分析触摸事件和按键事件在不同阶段被拦截的流程,总结在不同阶段不同方法中返回值的含义。 按键的拦截 (1)interceptKeyBeforeQueueing interceptKeyBeforeQueueing方法的意义就是在事件入队列前拦截按键事件,也就是如果…

想找工作,这一篇15w字数+的文章帮你解决

文章目录前言一 专业技能1. 熟悉GoLang语言1.1 Slice1.2 Map1.3 Channel1.4 Goroutine1.5 GMP调度1.6 垃圾回收机制1.7 其他知识点2. 掌握Web框架Gin和微服务框架Micro2.1 Gin框架2.2 Micro框架2.3 Viper2.4 Swagger2.5 Zap2.6 JWT3. 熟悉使用 MySQL 数据库3.1 索引3.2 事务3.3…

每日学术速递3.6

Subjects: cs.CV 1.Multi-Source Soft Pseudo-Label Learning with Domain Similarity-based Weighting for Semantic Segmentation 标题:用于语义分割的基于域相似性加权的多源软伪标签学习 作者:Shigemichi Matsuzaki, Hiroaki Masuzawa, Jun Miura …

2022掉队的“蔚小理”,按下了兔年加速键

配图来自Canva可画 进入2023年,各大车企又展开了新一轮的“竞速”。尽管1月份汽车整体销量出现了“阴跌”,但从各路车企发布的销量目标来看,车企对于2023依旧保持着较高的信心和预期。在一众车企中,以“蔚小理”为代表的新势力们…

基于quartz实现定时任务管理系统

基于quartz实现定时任务管理系统 背景 说起定时任务框架,首先想到的是Quartz。这是定时任务的老牌框架了,它的优缺点都很明显。借助PowerJob 的readme文档的内容简单带过一下这部分。 除了上面提到,还有elastic-job-lite、quartzui也是相当…

【C++】仿函数 -- priority_queue

文章目录一、priority_queue 的介绍和使用1、priority_queue 的介绍2、priority_queue 的使用3、priority_queue 相关 OJ 题二、仿函数1、什么是仿函数2、仿函数的作用三、priority_queue 的模拟实现一、priority_queue 的介绍和使用 1、priority_queue 的介绍 priority_queu…

vue3 transition动画

Vue 提供了 transition 的封装组件,通过它可以给任何元素和组件添加进入/离开过渡动画 一、vue怎么实现单组件/元素的过渡动画 Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。------vue官网 vue的transition组件通过观察元素的DOM状…

全网最全整理,自动化测试10种场景处理(超详细)解决方案都在这......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 自动化工作流程 自动…

三种让DIV标签中的P标签水平和垂直都居中方法

效果如下图 红色1块是span,属于行内元素。 绿色2块和蓝色4块是p,属于块级元素。 黄色3块h3,属于块 都是块级元素方法是可以通用的 这里两个类别元素一起来展示主要是为了区别 1行内块元素水平居中垂直居中 行内元素和行内块元素水平居中…

docker项目自动化部署脚本(认真排版、工作积累)

要解决什么问题? 把日益复杂化、工程化的开发环境,以及生产环境,变得简单,自动化部署。 达到什么效果? 环境处处一致,并且自动化部署,提升生产力,又快又好。 当您更换电脑、更换…