你好,欢迎进入江苏优软数字科技有限公司官网!

诚信、勤奋、创新、卓越

友好定价、专业客服支持、正版软件一站式服务提供

13262879759

工作日:9:00-22:00

爱奇艺的 "数据库" 选型到底有多牛逼?

发布时间:2023-12-03

浏览次数:0

选择数据库时我们应该考虑哪些问题? 有什么需求? 所选择的数据库是否满足需求? 可以直接使用吗? 是否需要一些额外的开发? 这些都会在本文的分享中提到。

intellij idea 数据库关系图_关系库的标准语言_数据库关系图在哪

1、选择数据库技术时的思考维度

当我们进行选择时,我们首先要问:

谁选择? 是负责采购的同学、DBA、还是业务研发?

如果是购买学生来选择,他们更注重成本,包括存储方式、网络要求等。

如果您是 DBA 学生,他们会担心:

① 运行维护成本

首先是运维成本,包括监控报警是否齐全,是否有备份恢复机制,升级迁移成本是否高,社区是否稳定,是否方便调优,是否排查问题简单等;

② 稳定性

其次,DBA会关注稳定性,包括是否支持数据多副本、服务高可用性、多次写入和多次活跃等;

③性能

三是性能,包括延迟、QPS以及是否支持更高级的分层存储功能;

④ 扩展性

第四是可扩展性。 如果业务需求不确定,横向和纵向扩展是否容易?

⑤安全

最后是安全性,需要符合审计要求,不易出现SQL注入或数据库拖拽。

⑥ 其他

除了采购和DBA之外,后端应用开发的同学也会关注稳定性、性能、扩展性等问题。 他们也会非常关注数据库接口是否容易开发,是否容易修改数据库。

intellij idea 数据库关系图_数据库关系图在哪_关系库的标准语言

接下来我们看一下爱奇艺使用的数据库类型:

可以看到,爱奇艺的数据库类型还是比较多的,这可能会导致业务开发同学在自己的业务场景中不知道该选择哪种数据库系统。

那么,我们首先按照接口(SQL、NoSQL)和面向业务场景(OLTP、OLAP)两个维度对这些数据库做一个简单、不严格的分类。

下图中,左上角是一类面向OLTP、支持SQL的系统,比如MySQL,一般支持不同的事务隔离级别,QPS要求比较高,延迟较低,主要用于交易信息和关键数据的存储。 如订单、VIP信息等。

关系库的标准语言_数据库关系图在哪_intellij idea 数据库关系图

左下角是NoSQL数据库,这是针对特殊场景优化的一类系统。 一般比较简单,吞吐量高,延迟低,一般用作缓存或者KV数据库。

整个右侧是一个OLAP大数据分析系统,包括OLAP等,一般支持SQL,不支持事务。 它具有良好的可扩展性。 可以通过添加机器来增加数据的存储容量,响应延迟较长。

还有一类数据库是相对中性的。 当数据量比较小时它有比较好的性能,当数据量很大或者查询复杂的时候也还不错。 它一般采用不同的存储引擎和查询引擎来满足不同的业务需求。 ,我们称之为HTAP,TiDB就是这样一个数据库。

2、爱奇艺对数据库的优化和完善

前面我们提到了很多种数据库,下面给大家介绍一下我们在爱奇艺是如何使用这些数据库的。

1、MySQL在爱奇艺的使用

①MySQL

第一个是MySQL。 MySQL的基本用法是-slave+半同步,支持每周全备份+每日增量备份。 我们做了一些基本的功能增强。 首先是增强数据恢复工具的性能。

我们之前遇到过一个情况。 我们有一个全量数据库,每天有300G数据intellij idea 数据库关系图,还有一个增量数据库,每天有70G数据。 总数据量约700G。 我们只需要恢复一张表的数据,但是该工具不支持单表恢复,整个数据库恢复需要5个小时。

我们专门排查了造成这种情况的原因,发现在数据恢复过程中,需要多次磁盘写IO操作,串行操作较多,所以我们做了一些优化。 例如,减少删除过程中的一些磁盘写操作,并行化数据处理。 优化后,整个数据库恢复时间缩短至100分钟,单表数据可直接恢复。

然后是DDL和DML工具对内部系统的适配。 gh-ostt和oak--alter-table在数据量较大时会造成-slave延迟,所以我们在使用工具时也加入了延迟考虑。 ,实时检测从库之间的延迟。 如果延迟较大,该工具的使用将暂停并恢复到正常水平,然后再继续。

② MySQL高可用

其次是MySQL的高可用。 -slave加半同步的高可用方式并不完美,所以我们参考MHA做了修改,采用+agent的方式。 Agent部署在每台物理机上,可以监控该物理机上所有实例的状态。 它定期向服务器发送心跳,实时监控各个Agent的状态。

如果MySQL出现故障,将启动补偿机制,切换访问域名完成。 考虑到数据库是跨机房、跨区域部署的,我们MHA也做了高可用的设计,很多会通过raft形成一个raft group,类似于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 的特点逐步迁移。

关系库的标准语言_数据库关系图在哪_intellij idea 数据库关系图

2、Redis在爱奇艺的使用

接下来是Redis。 Redis也采用slave方式。 由于网络的复杂性,我们为部署做了一些特殊的配置。 在多个机房的情况下intellij idea 数据库关系图,每个机房都配置一定的数量,避免脑裂。

在备份和恢复方面,我们介绍一个我们的特殊场景。 虽然Redis是一个缓存,但是我们发现很多商学院的同学把它当作KVDB使用,在某些情况下可能会导致数据丢失。

所以我们做了一个Redis实时备份功能,启动一个伪装成Redis Slave的进程实时获取数据,然后放入后端KV存储。 例如,如果你想恢复,你可以把数据拉出来。

我们使用Redis时最大的痛点是它对网络延迟或抖动非常敏感。 如果抖动导致Redis超时,则会选择一个新的节点,并将该节点上的数据同步到所有Slave。 在这个过程中,数据会被放置到节点中。 如果写入的QPS很高,就会造成溢出。 如果 RDB 文件已满时尚未复制,则重建过程将失败。

基于这种情况,我们对Redis报警进行了自动优化。 如果大量slave重建失败,我们会动态调整一些参数,比如暂时增加大小。 另外,我们还实现了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还具有一些功能,例如负载和故障检测。 比如某个节点延迟很高,就会暂时被烧断。

客户端分片的方式会让Redis的扩展变得非常痛苦。 如果客户端已经进行了一定量的分片,以后再增加就非常困难了。

Redis将在3.0版本之后提供。 由于功能有限,在爱奇艺并未得到广泛应用。 例如不支持跨DC部署和访问,读写只能在主库上。

我们在一些业务场景中会用到Redis集群。 例如,数据库访问只发生在这个DC中,我们将其部署在DC内部。

但有些商家在使用过程中还是想这么做。 如果集群出现故障,可以切换到其他集群。 基于这种情况,我们做了一个Proxy,通过它进行读写。 当写入数据时,Proxy会做一个旁路,将新数据写入Kafka中。 后台启用同步程序,然后将Kafka中的数据同步到其他集群。 然而,也有一些限制。 比如我们不做冲突检测,所以集群的数据需要商科学生进行单元化。 线上环境Redis集群间场景跨DC同步耗时约50毫秒。

intellij idea 数据库关系图_数据库关系图在哪_关系库的标准语言

3.在爱奇艺上使用

虽然Redis提供了这种部署方式,但是也存在一些问题。 因此,当数据量较大时(经验是160G),不建议使用Redis,而是使用另一种存储方式。

国内互联网公司很少使用。 最初,我们将其用作纯缓存系统。

但事实上,它的性能还是比较强大的。 它是一个分布式高性能KV系统,支持多种存储引擎()。 第一种使用方式和KV存储一样,不支持数据持久化,也没有数据副本。 如果某个节点发生故障,数据将会丢失;

二是支持数据持久化,使用Json写入,并且有副本。 我们通常在线配置两份。 如果添加新节点,则会处理数据。 爱奇艺一般采用此配置。

数据分布如下图所示。 数据写入时,首先在客户端进行哈希运算。 操作完成后,key就被定位了(相当于数据库中的某个分片)。 之后,客户端会根据Map向相应的服务器发送信息。 客户端的Map保存了与服务器端的映射关系。 服务器数据迁移过程中,客户端的Map映射关系会动态更新。 因此,客户端对服务器的操作不需要特殊处理,但过程中可能会出现短暂的超时,产生的报警对业务影响不大。

爱奇艺应用比较早,2012年开始使用,当时Redis还不存在。 集群管理是使用语言开发的,其最大的功能就是集群之间的复制。 提供多种复制方式:单向、双向、星型、环型、链型等。

爱奇艺从最初的版本到目前的5.0版本一直使用1.8版本。 正在考察的6.0在过程中也遇到了很多坑。 例如,NTP时间配置错误会导致崩溃。 如果各个集群的外部XDCR并发度过高,会导致不稳定和不同步。 方向改变会导致数据丢失等,我们通过运维和一些外部工具来避免这种情况。

集群是一个独立的集群,集群之间的数据同步是通过XDCR进行的。 我们一般将其配置为双向同步。 对于业务来说,如果写1,不写2,一般情况下客户端都会写1。 如果1有问题,我们提供Java SDK。 可以在配置中心将写入改为2,逐渐断开原来与1的连接,然后再与2建立新的连接。这个集群过程相对透明,对客户端不敏感。

数据库关系图在哪_关系库的标准语言_intellij idea 数据库关系图

4、爱奇艺自研数据库HiKV的使用

但性能非常高,并且数据可以存储在内存之外。 但是,如果数据量超过75%内存阈值,性能就会下降得特别快。 在爱奇艺,我们会控制可用内存内的数据量,并将其用作内存数据库。 但它的成本非常高,所以我们后来开发了一个新的数据库——HiKV。

开发HiKV的目的是为了将一些性能要求不那么高的应用迁移到HiKV上。 HiKV基于开源系统,主要利用其分布式数据库管理功能,增加了独立的存储引擎HiKV。

更吸引人的是,它号称性能提升十倍,接口完全兼容,设计基本一致,可以看作是C++版本的系统。

性能的提升主要得益于一些新的技术框架的使用,比如C++异步框架。 主要原理是每个物理机的核心上都会有一个应用线程,每个核心都有自己独立的内存、网络、IO资源。 核心之间没有数据共享,但它们可以通信。 最大的好处是内存访问没有锁定,也没有进程冲突。

当有读或写数据到达时,会通过哈希算法来判断请求的Key是否需要线程处理。 如果有则由本线程处理,否则转发给对应线程。

另外还支持多副本、多数据中心、多写多活,功能比较强大。

在爱奇艺,我们构建了基于SSD的KV存储引擎。 Key放在内存中,Value放在磁盘上的文件中。 当我们读写文件时,只需要在内存索引中定位,然后执行磁盘的IO开销来读取数据。 与原来的基于 LSM Tree 的存储引擎方法相比,IO 开销较小。

所有索引数据都存储在内存中。 如果索引长度过长,就会限制单机可以存储的数据量。 因此,我们开发了一个固定长度的内存分配器,对于相对较长的键,使用红色和黑色将摘要的长度缩短到20字节。 树索引将内存中每条记录的索引长度限制为64字节。 需要定期处理内存数据,客户端需要做限流、断路器等。

HiKV目前在爱奇艺广泛使用,目前已经替代了30%,有效降低了存储成本。

intellij idea 数据库关系图_关系库的标准语言_数据库关系图在哪

5、爱奇艺的数据库运维管理

爱奇艺数据库种类繁多,如何高效运营、维护和管理这些数据库经历了不同的阶段。

最初,我们通过 DBA 编写脚本来管理它。 如果脚本有问题,我们就会打电话给DBA,这让DBA非常忙碌。

第二阶段我们考虑让大家自己检查问题答案,所以我们内部搭建了一个私有云,通过Web展示数据库运行状态,让商学院的同学可以自己申请集群,一些简单的操作就可以也可以通过自助平台的实现解放DBA。 一些需要人工处理的大规模运维操作,往往会造成一些人为失误、参数错误导致数据丢失等。

所以第三阶段我们把运维操作做成了Web化,90%的操作都可以通过点击网页来进行。

第四阶段让有经验的DBA将自己的经验转化为一些工具。 比如业务同学说MySQL-slave延迟了,DBA会通过一系列的操作来排查问题。 现在我们将这些操作串在一起形成一套工具。 当出现问题时,商科学生可以利用网页上的一键诊断工具自行排查和处理。

此外,我们还会定期进行预警排查,针对业务集群潜在问题做出预警报告; 开发智能客服解答问题; 通过监控数据对实例进行标签,进行调峰填谷智能调度,提高资源利用率。 速度。

3、不同场景下数据库选型建议

1. 实用数据库选择树

最后说一下一些具体的数据库选择建议。 这些是DBA和业务共同通过经验得出的一些结论。

对于关系型数据库的选择,可以从数据量和可扩展性两个维度来考虑,然后根据数据库是否有冷备份、是否使用Toku存储引擎、是否使用Proxy等来做出决定。

数据库关系图在哪_关系库的标准语言_intellij idea 数据库关系图

NoSQL还解释了何时使用-slave,何时使用客户端分片、集群、HiKV等。这个选择树信息可以在我们内部的自助服务平台上获得。

数据库关系图在哪_intellij idea 数据库关系图_关系库的标准语言

2.一些想法

① 需求

在选择型号时,我们首先思考需求,判断需求是否真实。

你可以从数据量、QPS、延迟等方面考虑需求,但这些是真正的需求吗? 这个需求可以通过其他方式消耗吗? 例如,如果数据量较大,可以先进行数据编码或压缩,可以减少数据量。

不要将所有需求都推到数据库级别,它实际上是一个隐蔽的系统。

② 选择

第二点思考是我们在选择某种数据库系统或者某种技术时应该考虑什么? 是因为受欢迎吗? 还是因为技术更先进? 但这并不能真正解决你的问题吗? 如果你的数据量不是很大,就没有必要选择能够存储大量数据的系统。

③ 放弃

第三是放弃。 当你放弃一个系统时,真的是因为它不起作用吗? 还是工作不顺利? 放弃一些东西是很难的,但放弃时最好有充分的理由,包括实际测量的结果。

④ 自主研发

四是自主研究。 当需要开发自己的数据库时,可以参考和使用一些成熟的产品,但不要盲目自研。

⑤ 开源

最后一件事是开源。 你必须有拥抱开源的态度。

intellij idea 数据库关系图_关系库的标准语言_数据库关系图在哪

选择数据库时您会考虑哪些因素? 欢迎留言告诉大家你的想法~

如有侵权请联系删除!

13262879759

微信二维码