Décrire l'écologie technique du big data ? Quelle est la relation entre Hadoop, Hive et Spark

Auteur : Little Monster
Lien : https://www.zhihu.com/question/27974418/answer/1862026844
Source : Zhihu
Le droit d'auteur appartient à l'auteur. Pour une réimpression commerciale, veuillez contacter l'auteur pour autorisation, pour une réimpression non commerciale, veuillez indiquer la source.

1

Hadoop n'est qu'un terme général désignant un ensemble d'outils. Il se compose de trois parties : HDFS, Yarn et MapReduce. Les fonctions sont le stockage de fichiers distribué, la planification des ressources et l'informatique.

Logiquement parlant, cela suffit, et l'analyse de données volumineuses peut être complétée.

Mais le premier problème est gênant. Cet ensemble équivaut à utiliser Yarn pour planifier des ressources et lire le contenu des fichiers HDFS pour le calcul MR. Vous voulez écrire du code Java, mais quel est le meilleur outil pour faire des données ? SQL ! Hive équivaut donc à la SQLisation de cet ensemble de processus standards.

Hive peut être simplement compris comme ajoutant son propre analyseur et optimiseur SQL à Hadoop, en écrivant un morceau de SQL, en l'analysant en code Java, puis en exécutant MR. Les données sous-jacentes sont toujours sur HDFS.

Cela semble parfait, mais le problème est que les programmeurs le trouvent si lent. La raison en est MR, qui doit écrire et lire fréquemment des fichiers. À cette époque, le Spark basé sur la mémoire est apparu. Spark remplace MR. Il génère des graphes acycliques dirigés pour SQL, et avec l'optimisation de divers opérateurs et des dépendances à largeur étroite, la vitesse de calcul atteint un nouveau sommet.

Il va de soi que cela est parfaitement résolu.

Mais, réfléchissons-y, d'où viennent ces données ? Avons-nous eu affaire à des données statiques jusqu'à présent ? Des choses comme la vérification des paiements en ligne qui doivent renvoyer des résultats en temps réel ne peuvent pas attendre que Spark calcule par lots.

Avant de résoudre le problème, revenons en arrière et réfléchissons à la provenance des données. Il existe deux types de données générales : les données d'entreprise et les données de journal.

Les données métiers sont les données structurées dans la base de données, régulières et soignées. Comment les données d'entreprise parviennent-elles à Hive ? L'open source est généralement importé via Sqoop, comme une table, s'il y a peu de données, j'importerai toutes les tables tous les jours, ce qui s'appelle une synchronisation complète ; si les données sont très volumineuses, seuls les changements quotidiens et les nouveaux ajouts seront synchronisés, ce qui est une synchronisation incrémentielle.

Cependant, ce type de synchronisation est à la traîne et se fait en pleine nuit lorsque les ressources informatiques du cluster sont relativement inactives, et l'analyse hors ligne correspondante est également effectuée.

Comment obtenir les données en temps réel ?

2

Comment comprendre en temps réel ? Venez traiter un lot, puis obtenez un peu plus de détails, venez en un et traitez-en un.

Par exemple, si vous achetez quelque chose, il y aura des données de commande supplémentaires dans la base de données de la plate-forme et l'application générera des données de journal de comportement. Lorsque les données de commande sont insérées dans la base de données, il existe généralement un binlog , qui enregistre les données insérées, mises à jour ou supprimées. Tant que nous pouvons obtenir ce binlog en temps réel, cela équivaut à obtenir des données en temps réel.

Comment obtenir binlog ? Cela signifie que le mécanisme de sauvegarde maître-esclave de la base de données est généralement synchronisé avec le binlog de la base de données principale vers la base de données de sauvegarde. Il existe un outil appelé canal qui peut se déguiser en base de données de sauvegarde pour extraire le journal binaire de la base de données principale, l'analyser, le conditionner et enfin le jeter, ce qui équivaut à obtenir les données en temps réel !

Le canal peut-il le gérer directement après avoir obtenu le binlog ? Oui, mais il y a une chose à laquelle tout le monde doit penser. Le 1er mai arrive bientôt, tant de gens passent des commandes et consomment en même temps, et si les nouvelles de canal ne pouvaient pas être consommées toutes en même temps ? Par exemple, le coursier ne vous enverra qu'un seul coursier par jour et vous paierez les marchandises après les avoir reçues. Puis soudain un jour le coursier vous a envoyé mille pièces en bas, et vous êtes descendu pour les déplacer une par une, et le coursier a dû attendre que vous ayez fini de les déplacer avant de repartir. Vous êtes intelligent et vous y avez immédiatement pensé, mettez-le dans l'armoire express, vous pouvez le déplacer lentement si vous avez le temps, et cela ne prendra pas le temps du courrier.

Il s'agit de la file d'attente des messages, et Kafka joue un tel rôle : asynchrone, découplé et élimination des pics. Les données du canal sont généralement envoyées à Kafka ou RocketMQ, qui peuvent être stockées pendant un certain temps. Ensuite, le programme en aval extrait le message en temps réel pour le calculer.

3

Ceci dit en aval, qui va consommer et calculer ces données temps réel en aval ? Rappelez-vous Spark, oui c'est encore là, le streaming Spark est un bon lecteur pour traiter les données de streaming en temps réel.

Spark est un terme général désignant un ensemble complet de composants. Par exemple, vous pouvez écrire des tâches Spark en Java, écrire du SQL dans Spark SQL et effectuer une formation de modèle d'apprentissage automatique avec Spark MLib. Spark Streaming est utilisé pour traiter des flux de données en micro-lots.

具体而言,离线数据我们是等半夜数据都抽到 Hive 中再计算,而 Spark Streaming 则是实时数据来一小批,它就处理一小批。所以本质上讲,Spark Streaming 还是批处理,只不过是每一批数据很少,并且处理很及时,从而达到实时计算的目的。

Spark 本身的流行使得 Spark Streaming 也一直大范围使用。

这一套有什么逻辑缺陷吗?

我们可以想一想,实时数据和离线数据最大的差异,是时效性。离线数据像湖水,该多少就多少,就在那里;实时数据像水流,绵绵不绝。时间,便是非常重要的一个特质。当一条数据来的时候,我们需要知道这条数据是什么时候产生的,这便是业务时间。但我们拿到这条数据时往往是业务时间之后的一小会,这边是处理时间。真正世界里的实时数据肯定不是像 Spark Streaming 那样一批一批来的,而是一个一个的事件。对此,Flink 帮助我们解决了这些问题。

4

无论是业务数据还是日志数据,往往都有相应的时间标志字段,代表着这条消息的业务时间。你可以让 Flink 选择这个时间,这样,Flink 就知道当前处理到哪个时间点了。

Flink 不同于 Spark Streaming 的微批次处理,它是一条一条数据处理的。这样的数据一般是先来后到的,但难免会有些数据沿途受阻晚来了几秒钟,这就会导致两个问题:数据延迟和乱序数据。这也是做实时数据的非常关注的问题。

如何防止数据延迟?如果是上游数据迟了,就加大上游资源;如果是数据突然激增,导致 Flink 处理不过来导致任务出现延迟,就加大 Flink 的资源,比如并发。

数据乱序呢?

同样的,我们一般也通过上游和 Flink 本身来分别保证。

我们上面提到了消息的快递柜 Kafka,Kafka 有分区的概念,就像是不同的通道,一条消息来了后,可以走 A,也可以走 B,也可以走 C。那么问题来了,现在面试官问你,业务数据抛入 Kafka,如何保证消息的顺序性呢?

(5月4日 更)

顺序性一般有两方面需要保证。我们举一个小小的例子,一个用户下单的场景,有两个基本共识:

  1. 同一个用户的订单状态会先后变化;
  2. 不同用户的不同订单也有先后之分。

所以我们解决数据的顺序性一般也是从这两方面考虑。如果你还记得大学高数里的多元函数求偏导,对于 x 和 y 两个变量,求 x 的偏导会假设 y 为常量,反之同理。我们考虑这个问题也一样,如果不能同时兼顾这两方面,那就一个一个去优化吧!这种思想也称为贪婪算法,在很多地方都有应用,这里暂时说到这里。

回到问题,那么如何保证同一用户的订单顺序呢?很简单,前面我们提到的链路是,数据库中插入或更新数据时,会实时产生该条数据的 binlog,canal 获取、解析、包装这条 binlog 并抛入 Kafka。

而 Kafka 由于有分区的存在,很可能同一个订单的消息会被发送到不同的分区中,这样的话,如果下游的 Flink 任务消费不同分区速率不同,就可能导致先到的数据反而被后消费,产生顺序误差。解决的办法即保证同一订单的消息进入 Kafka 的同一分区即可。

Kafka 的每一条消息都会有 messageKey 和 message 两个结构,如果没有直接给消息指定分区,那么 messageKey 决定了消息进入哪个分区,在 canal 中,我们便可以设定消息如何进入 Kafka。数据库中的业务数据,会存在一张张的表中,表一般都会有主键,来唯一标识一条数据,我们一般也就是通过设定 canal 选择 binlog 所在表的主键来决定其进入 Kafka 的分区。这样,就基本解决了第一个问题。

(5月9日 更)

但这只保证了同一订单数据的顺序性,并未保证不同订单之间的顺序性。聪明的你可能已经想到,如果 Kafka 只设定一个分区那不就保证了吗?但这其实算是本末倒置,Kafka 本身相当于快递柜,多个分区相当于多个柜子,能存储更多的数据,提高并发,如果为了顺序性而牺牲并发量,那就得不偿失了,而且一般本身数据的乱序无论是在概率和重要性方面都不如并发重要的。就比如我要统计每小时的订单数,即使数据乱序了,只要在窗口区间内计算结果也不怎么受影响。

但这并不是说我们就不考虑数据在全局的顺序性了。

我们如何去认识乱序或延迟数据呢?

既然这种情况是偶发性的,那么一般可以这么做,在实时的流数据中,如果想要拿到 T 时刻的数据,只要等一小会儿比如 1s,就能保证在 T+1s 的时刻拿到 T 时刻的所有数据。

上面这句话其实理解起来也很简单,比如幼儿园老师组织小朋友们春游,约定了早上 8:00 集合发车,即 8:00 触发一个事件。但总有那么几个调皮捣蛋的学生会迟到几分钟,于是老师说好的 8 点发车实际上是8:05,大家觉得也没啥问题,回家就跟家长说,我们今天 8:00 发车春游啦。

在 Flink 中,这种机制就叫做 watermark。

上面我们说过,每一条数据一般都会自带一个时间字段,来标志这条数据的业务时间,即什么时候发生的。然后 Flink 提取这个时间字段,就知道了目前 Flink 任务进行到几点了。

那么既然要考虑乱序或迟到数据,我们一般也会让 Flink 当前的时间稍微迟几秒钟。比如我们认为大部分情况下乱序或迟到的数据都在 1s 以内,那么来一条数据,比如这条数据自带的时间是 08:00:01,那我们就认为 08:00:00 时刻的数据才刚到齐。但回过头来说,在大多数场景下,毕竟乱序或迟到数据算是占比很小了。

5

是不是看到这里有点抽象了?下一节我们聊聊 SQL 吧

Guess you like

Origin blog.csdn.net/haoweng4800/article/details/128564659