发布时间:2023-06-05
浏览次数:0
我们在选择数据库时应该考虑哪些问题? 你有什么需求? 所选择的数据库是否符合要求? 可以直接用吗? 需要一些额外的开发? 这个在本文的分享中会提到。
一、数据库技术选型的思考维度
当我们进行选择时,我们首先会问:
谁选择? 是负责采购的朋友,DBA还是业务开发的?
如果是采购的朋友,他们更看重成本,包括存储方式、网络要求等。
如果你选择一个 DBA 朋友,他们关心的是:
①运维成本
首先是运维成本,包括监控告警是否健全,是否有备份恢复机制,升级迁移成本是否高,社区是否稳定,调优是否方便,是否容易排错;
②稳定性
其次,DBA会关注稳定性,包括是否支持数据多副本、服务的高可用、多写多活等;
③性能
第三是性能,包括延迟、QPS、是否支持更多的中间分层存储功能等;
④ 扩展性
第四个是可扩展性。 如果业务需求不确定,是否容易纵向横向扩展;
⑤安全
最后是安全性,必须满足审计要求,不容易出现SQL注入或者数据库拖拽。
⑥其他
除了采购和DBA,开发后台应用的朋友也会关注稳定性、性能、扩展性等问题。 同时,他们也很关心数据库是否好开发,是否容易改数据库。
接下来我们看一下爱奇艺使用的数据库类型:
由此可见,爱奇艺的数据库种类还是比较多的,这可能会导致业务开发的朋友不清楚在自己的业务场景中应该选择哪种数据库系统。
那么,我们先按照(SQL、NoSQL)和业务场景(OLTP、OLAP)两个维度,对这类数据库做一个简单的、不严谨的分类。
右图中,左上角是一类面向OLTP,支持SQL的系统,比如MySQL,通常对事务支持不同的隔离级别,对QPS要求比较高,延迟也比较低,主要用于交易信息和关键数据的存储。 比如订单、VIP信息等。
左下角是NoSQL数据库,是针对特殊场景优化的一类系统。 它通常比较简单,具有高吞吐量和低延迟。 它通常用作缓存或 KV 数据库。
整个右侧是OLAP大数据分析系统,包括等,通常支持SQL,不支持事务,扩展性较好。 可以通过增加机器来减少数据存储量,响应延迟更长。
还有一类数据库相对中性。 它在数据量比较小的时候表现比较好,在数据量大或者复杂查询的时候表现也不错。 通常,使用不同的存储引擎和查询引擎来满足不同的需求。 业务需求,我们称之为HTAP,TiDB就是这样一个数据库。
2.爱奇艺优化建立数据库
后面我们讲了很多种数据库,我给大家介绍一下我们在爱奇艺是怎么使用这种数据库的。
一、MySQL在爱奇艺的使用
①MySQL
首先是MySQL。 MySQL的基本使用方式是-slave+半同步,支持每周全量备份+每天增量备份。 我们进行了一些基本的功能增强,首先是提高数据恢复工具的性能。
我之前遇到过一个情况。 我们有一个300G数据的全量数据库,一个每晚70G数据的增量数据库,总数据量大约700G。 当时我们只需要恢复一张表的数据,但是工具不支持单表恢复,整个数据库恢复需要5个小时。
针对这种情况,我们详细排查了原因,发现在数据恢复的过程中,需要进行多次写磁盘的IO操作和大量的串行操作,所以我们做了一些优化。 比如剪枝过程中的一些磁盘写操作,可以减少磁盘数量,并行处理数据。 优化后全库恢复时间缩短至100分钟,单表数据可直接恢复。
然后在内部系统适配DDL和DML工具,gh-ostt和oak--alter-table在数据量大的时候会造成-slave延迟,所以我们在使用工具的时候也要减少延迟考虑实时检测Slave库之间的延迟,如果延迟大于使用会议挂起工具,恢复到正常水平再继续。
②MySQL高可用
二是MySQL高可用。 -slave加半同步等高可用的方式不好建立,所以我们参考MHA做改动,采用+agent的形式。 Agent部署在每台数学机上,可以监控数学机上所有实例的状态,定期向服务器发送脉冲,实时检测每个Agent的状态。
如果MySQL出现故障,将启动补偿机制,完成访问域名的切换。 考虑到数据库跨机房、跨区域的部署,我们也对MHA做了高可用的设计,其中很多会通过raft组成一个,类似于TiDB的PD模块。 目前MySQL策略支持三种形式:同机房、同地域跨机房、跨地域。
③MySQL扩展能力
三是增强MySQL的扩展能力,提供更大容量的数据存储。 扩展方式有SDK,比如开源的,在爱奇艺也有广泛使用。 另一个是Proxy,开源的比较多。 而且使用SDK和Proxy的问题是支持的SQL语句简单,扩展困难,依赖多,运维复杂,所以部分业务已经迁移到TiDB。
④审计
四是审计。 我们在MySQL上做了一个插件,获取完整的SQL操作,前端打Kafka,下游访问包括等待目标端进行SQL统计分析。 此外还有安全策略,包括主动探索是否存在SQL注入和数据库拖拽,并触发相应的告警。
MySQL审计插件最大的问题是如何增加对MySQL性能的影响。 我们对此进行了一些测试,发现使用Log有很大的性能损失,有10%到20%的提升。
所以我们在MySQL插件中使用获取监控项,然后将监控项放入其中,使用两级保证数据写入不会出现锁资源竞争。 在这个插件中启动另一个线程,从中读取数据并将数据打包到 FIFO 管道中。
我们在每台MySQL化学机中启动一个Agent,从管道中读取数据并发送给Kafka。 优化后,我们再次进行了压力测试。 每台机器15万次、、操作下没有数据丢失,性能损失通常大于2%。
目前公司集群已经上线一年,运行比较稳定。 线上线下对业务没有影响。
⑤ 分级存储
五是分层存储。 MySQL会存储一些过程性的数据,即只需要读写最近一段时间存储的数据,一段时间后就不需要这种数据了,需要定时清除。
分层存储是指在 MySQL 之上使用其他存储方式,比如 TiDB 等。 两者之间可以手动移动和归档数据,后台使用SDK+Proxy作为统一的访问入口。 这样业务开发的朋友只需要将数据存储在MySQL中,读取时可以从前端连接的任意数据库中读取。 这些方法目前只是过渡使用,之后会根据 TiDB 的特点逐步迁移。
二、Redis在爱奇艺的使用
连接是Redis。 Redis也使用了-slave的方法。 由于网络的复杂性,我们针对部署做了一些特殊的配置。 在多个机房的情况下,每个机房配置一定的编号,以防止脑裂。
在备份和恢复方面,我们介绍一个特殊的场景。 Redis其实就是一个缓存,但是我们发现很多业务同学把它当作KVDB来使用,在某些情况下可能会导致数据丢失。
于是我们做了一个Redis实时备份的功能,启动一个伪装成Redis Slave的进程实时获取数据,然后放到前端的KV存储中。 例如,如果你想恢复,你可以从中拉取数据。
我们在使用 Redis 时最大的痛点是它对网络延迟或者抖动非常敏感。 如果有任何抖动导致Redis超时,就会重新选举一个新的节点,然后把这个节点上的数据同步到所有的slave上。 在这个过程中,数据会被放置在节点中。 如果写入的QPS很高,就会造成溢出。 如果RDB文件写满后还没有复制,重建过程就会失败。
基于这些情况,我们对Redis告警进行了手动优化。 如果有大量-slave重构失败,我们会动态调整一些参数,比如临时增加size等,我们也实现了Redis集群的手动扩缩容功能。 .
我们在做Redis开发的时候,如果是Java语言,就会用到Jedis。 使用 Jedis 访问客户端分片的 Redis 集群。 如果一个分片发生故障,Jedis 将重新连接所有前端分片。 如果某个分片出现问题,整个Redis的访问性能和QPS都会急剧下降。 我们针对这种情况优化了 Jedis。 如果一个分片失败,它只会为这个分片重建。
当业务访问Redis时,我们会绑定一个读写域名,从库中绑定多个读写域名。 但是如果继续的话,读写域名会从一个旧的节点上解绑,然后绑定到一个新的节点上。
DNS本身有超时时间,所以如果业务程序在建库完成后没有立即获取到新节点的IP,可能会连上原机,导致访问失败。
我们的解决方案是缩短DNS的TTL,但是会对DNS服务造成很大的压力,所以我们在SDK上提供了Redis名称服务RNS,RNS可以从中获取集群拓扑和拓扑变化。 如果是集群的话会通知,客户端可以通过RNS获取新节点的IP地址。 我们去掉域名,通过IP访问整个集群,屏蔽DNS超时,缩短故障恢复时间。
SDK上还有一些功能,比如Load,故障检测等。 例如intellij idea 数据库关系图,如果一个节点延迟很高,它会被暂时吹灭。
客户端分片的形式会导致Redis的扩容非常痛苦。 如果客户端已经完成了一定量的分片,再减少就非常困难了。
Redis将在3.0版本之后提供Redis。 由于功能有限,爱奇艺里面的应用并不多。 比如不支持跨DC部署访问,读写只在主库上。
我们在个别业务场景中使用 Redis 集群。 比如数据库访问只发生在这个DC,我们就部署在DC内部。
但是,有些商家在使用过程中还是想做。 如果集群出现故障,可以切换到其他集群。 基于这些情况,我们做了一个Proxy,通过它进行读写。 Proxy在写数据的时候会做一个旁路,把新添加的数据写到Kafka里面,后台开启同步程序,然后把Kafka里面的数据同步到其他集群,但是有一些限制,比如我们不做冲突检查,所以集群的数据需要业务友们联合起来。 有线环境Redis跨集群场景跨DC同步需要50微秒左右。
3.在爱奇艺中使用
Redis似乎提供了这些部署形式,但是存在一些问题。 因此,当数据量较大时(经验是160G),不推荐使用Redis,而是采用另一种存储方式。
国外的互联网公司很少用。 一开始我们把它当成一个,也就是一个纯缓存系统。
但是可能它的性能比较强,是一个分布式的高性能KV系统,支持多种存储引擎()。 第一种是使用和KV存储一样的方式,不支持数据持久化,没有数据副本。 如果节点发生故障,数据将丢失;
二是支持数据持久化,用Json写,有副本。 我们一般在线配置两份。 如果增加一个新的节点来进行数据处理,爱奇艺通常会使用这些配置。
数据分布如右图所示。 写入数据时,会先在客户端进行哈希运算。 运行后会定位到key(相当于数据库中的某个分片)。 以后会根据Map向对应的发送信息。 客户端的Map存储着与服务端的映射关系。 在服务端数据迁移过程中,客户端的Map映射关系会动态更新。 因此,客户端对服务端的操作无需特殊处理,但过程中可能会出现短暂的超时,由此产生的告警对业务影响不大。
爱奇艺的应用比较早,2012年开始用,当时还没有Redis。 集群管理是使用语言开发的,其最大的功能是进行集群间的复制,提供多种复制方式:双向、双向、星型、环型、链型等。
爱奇艺一直在用原来的1.8版本到现在的5.0版本,在监管下的6.0,中间也遇到了很多坑,比如NTP时间配置错误会导致死机,如果每个集群的外部XDCR并发是低,造成不稳定,同步方向改变会造成数据丢失等,我们使用运维和一些外部工具来避免。
集群是一个独立的集群,集群之间的数据同步是通过XDCR进行的intellij idea 数据库关系图,通常配置为单向同步。 对于业务来说,写1不写2,一般情况下客户端会写1。 如果1出现故障,我们提供了一个,可以在配置中心修改对2的写入,逐渐断开原来与1的连接,然后再与2建立新的连接。这些集群的过程相对透明,不敏感客户。
4.爱奇艺自研数据库HiKV的使用
虽然性能很高,而且数据存储可以超过显存。 而且,如果数据量超过显存75%的阈值,性能提升会非常快。 在爱奇艺,我们会把数据量控制在显存可用范围内,作为显存数据库使用。 而且它的成本非常高,所以我们开发了一个新的数据库——HiKV。
开发HiKV的目的是将一些对性能要求不高的应用迁移到HiKV上。 HiKV基于开源系统,主要利用其分布式数据库的管理功能,减少了单机存储引擎HiKV。
更吸引人的是,号称性能低于十倍,而且完全兼容插座,设计基本一致。 可以看作是一个C++版本系统。
性能的提升主要是由于使用了一些新的技术框架,比如C++异步框架。 主要原理是每个化机的核心上都会有一个应用线程,每个核心都有自己独立的显存、网络、IO资源。 核心之间没有数据共享,但它们可以通信。 它最大的用处是显存访问是无锁的,没有进程冲突。
当有数据读写到达时,会根据哈希算法判断请求的Key是否需要本线程处理。 如果有,则本线程处理,否则转发给相应的线程。
另外,它还支持多副本、多数据中心、多写多活,功能比较强大。
在爱奇艺,我们构建了基于SSD的KV存储引擎。 键放在显存中,值放在磁盘上的文件中。 当我们读写一个文件时,只需要在显存索引中定位到它,然后执行一次磁盘IO开销就可以读取数据了。 与原来基于 的存储引擎方式相比,在 IO 上的开销更小。
所有索引数据都放在显存中。 如果索引宽度较长,单机所能存储的数据量就会受到限制。 因此,我们开发了一个定长的显存分配器,通过开发一个定长的key来将宽度缩短到20字节。 红树林索引,限制显存中每条记录的索引宽度为64字节。 显存数据需要定时做,客户端需要做限流和熔断。
HiKV目前在爱奇艺应用广泛,目前已替换30%,有效降低存储成本。
5.爱奇艺的数据库运维管理
爱奇艺数据库种类繁多,如何高效地运营、维护和管理这些数据库经历了不同的阶段。
起初,我们由 DBA 编写脚本进行管理。 如果脚本有问题,我们就联系DBA,这让DBA很忙。
第二阶段,我们考虑让大家自己查题答案,所以我们在内部搭建了一个私有云,通过Web展示数据库的运行状态,方便业务朋友自己申请集群,还有一些简单的操作也可以通过自助平台的实现解放DBA。 一些需要人工处理的小运维操作,经常会出现一些人为失误,输入错误的参数导致数据丢失等情况。
所以在第三阶段,我们把运维操作网页化,90%的操作都可以通过网页点击来完成。
第四阶段让有经验的 DBA 将自己的经验转化为一些工具。 比如业务上的朋友说MySQL-slave延迟了,DBA会通过一系列的操作来排查问题。 现在我们把这种操作串起来生成一套工具。 出现问题时,业务朋友可以使用网页一键诊断工具自行排查处理。
此外,我们会定期进行预警审查,报告业务集群存在的潜在问题; 开发智能客服答疑解惑; 利用监控数据对实例进行标注,进行移峰填谷的智能调度,提高资源利用率。
3、不同场景下的数据库选择建议
1.实用的数据库选择树
最后,一些具体的数据库选择建议。 这是DBA和业务通过经验总结下来的一些推论。
对于关系型数据库的选择,可以考虑数据量和扩展性两个维度,然后根据数据库是否冷备份、是否使用Toku存储引擎、是否使用Proxy等进行选择。
NoSQL在什么情况下也使用-slave,在什么情况下它使用客户端分片、集群、HiKV等。这个选择树信息在我们内部的自助服务平台上有。
2.一些想法
①需求
在选择模型时,我们首先考虑需求,并确定需求是否真实。
可以考虑数据量、QPS、时延等方面的需求,但是这些都是真实的需求吗? 是否可以使用其他方式来消费这个需求,比如数据量很大,可以先对数据进行编码或者压缩,可能会减少数据量。
不要把所有的需求都推到数据库层面,好像是一个自下而上的系统。
②选择
第二个思考点是对于某个数据库系统或者某个技术选型我们应该考虑什么? 是因为人气吗? 还是因为更先进的技术? 它真的不能解决你的问题吗? 如果您的数据量不是很大,则不需要选择能够存储大量数据的系统。
③放弃
三是放弃。 当你放弃一个系统,真的是因为它不好用吗? 还是行不通? 放弃一些东西是很难的,但是放弃的时候最好有一个好的理由,包括衡量的结果。
④自主研发
四是自主研究。 当需要开发自己的数据库时,可以参考和使用一些成熟的产品,但不要盲目自研。
⑤开源
最后是开源,我们要有拥抱开源的心态。
您在选择数据库时考虑了哪些激励因素? 欢迎评论留言告诉你你的看法~
如有侵权请联系删除!
Copyright © 2023 江苏优软数字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服务提供商
13262879759
微信二维码