在Hadoop集群从1.0升级到2.0之后,我们一直在解决很多很多的问题。在今年8月初,我们检测到线上频繁有机器变成死亡结点,一段时间后自动恢复。进入死亡结点状态的DataNode将不能读写数据块。我们观察了一下日志,看到DataNode中打印出很多接受数据快传输的线
在Hadoop集群从1.0升级到2.0之后,我们一直在解决很多很多的问题。在今年8月初,我们检测到线上频繁有机器变成死亡结点,一段时间后自动恢复。进入死亡结点状态的DataNode将不能读写数据块。我们观察了一下日志,看到DataNode中打印出很多接受数据快传输的线程(DataXceiver),线程都是在Receiving的状态,而没有结束。估摸了一下在死亡结点发生的阶段大约有300个左右的线程积累下来。但是,没找到其它突破口。
由于,HDFS的Client会自动重试。如果一个结点进入死亡结点,只要另外的数据块的结点依然可读,Client还是可以读取到数据块的。所以,死亡结点的问题对线上业务没有造成影响。当时,还有其它优先级更高的事情,所以,问题转为观察状态。
然后终于在一次机房意外断电,集群重启之后,一个线上的作业报找不到数据块。经日志确认,产生的原因是拥有这个数据块副本的两个机器同时进入死亡结点! 于是,问题转入高优先级,优先解决。
现象总结
- 出现死亡结点的机器集中在磁盘数量较多的机器。
- 死亡结点跟机器的CPU,内存或者网络关系不大。
- 出现死亡结点的时候,DataNode有大量DataXceiver的线程积压。
- 虽然,总体上机器出现死亡结点的时间比较分散。但是,单一的DataNode上出现死亡结点的间隔必然是6小时或者6小时的整数倍。
攻坚
首先知道,DataNode进入死亡结点状态是因为NameNode长期接收不到DataNode的心跳包,就会把DataNode归入死亡结点。而DataNode的心跳线程是单独一个线程。
现象的最后一点,6小时的间隔,可谓是这个问题的突破点。在配置文件中找到6小时的间隔的工作有两种:
- DataNode和NameNode的6小时一次的心跳报告。用于更新NameNode上的Block信息。
- DataNode每6小时一次的磁盘扫描。用于更新内存中的信息和磁盘中信息的不一致。
根据两者打印的日志和死亡结点发生的时间进行精确对比,发现后者的时间基本吻合。 然后,我们在集中查看磁盘扫描(DirectoryScanner)的代码。
描述一下磁盘扫描的工作流程:
- 启动一个主线程和一个线程池。
- 主线程往线程池提交多个磁盘扫描的任务。任务是遍历整个数据目录记录所有的数据块的信息和对应的Meta信息
- 主线程等待线程池的任务返回,收集扫描结果。
- 将扫描结果和内存中的数据块进行对比,得到DiffRecord,算法复杂度O(n),数据块越多速度越慢。
- 根据DiffRecord修改对应的内存数据。
第一步,主线程和线程池的线程都是Daemon线程。Daemon线程的默认优先级比较低。
第二步,由于涉及到磁盘读写。如果,外部磁盘压力大的时候,会拖慢整个进度。但是,整个过程没有加锁。不可能对其它线程产生影响。
第四步,数据块对比过程,为了阻止对blockMap的修改,整个过程针对DataSet对象加锁(DataSet对象是DataNode中保存所有数据块信息的内存对象)。
那心跳进程为什么会使用DataSet的对象锁? 我们写了个小程序测试,在对DataSet加锁的情况下,启动心跳线程。发现心跳线程在获取磁盘的可用空间的时候,需要获得DataSet的锁。
于是,问题变得清晰了:在6小时一次的磁盘扫描中,由于DirectoryScanner长久占用了DataSet的锁,导致心跳线程不能发出心跳包。DataNode进入死亡结点状态。而问题频发在磁盘较多的机器是因为,数据块数量和对比的过程的耗时相关。那是什么原因导致DirectoryScanner长久占用了DataSet的锁呢?
我们观察了加锁部分的代码,没有找到磁盘操作。我们估摸了下,最多数据块的机器也才80W左右各数据块。如果是纯内存操作,不可能占用锁长达10分钟甚至30分钟之久。
然后我们将怀疑的地方锁定在主线程的Daemon属性。因为,Daemon属性的线程优先级较低,怀疑是主线程在多线程的情况下,分配不到CPU时间片。
于是,我们作出第一个修改:将主线程改为普通线程的优先级。
上线第二天,死亡结点现象还是出现,现象出现的时间相对来说是短了点,但还是不能解决问题。
于是,我们开了个大招:针对死亡结点频发的结点,加上一个每分钟打印一次DataNode的jstack的脚本。
终于我们捕获了在死亡结点发生时候的几个堆栈。经过对比分析,得出的结论是:
(呵呵)数据块对比过程中,有一个使用Java的File对象的获取文件长度的getlength方法。而这个方法是直接调用一个native方法,获取磁盘上文件的长度。
当初我们就猜想,加锁部分是否有磁盘的IO操作。因为IO操作的快慢,会受到当时的机器状态影响很大。不得不说,这个位置太隐蔽了。看了很久都没发现,还好有jstack截获出来。
总结
6小时一次的DirectoryScanner在数据块对比过程中,会对DataSet加锁。如果,机器的磁盘压力很高的情况下,对比过程中的磁盘操作十分耗时。导致DirectoryScanner长期持有DataSet的锁,阻塞心跳线程和所有的DataXceiver的线程。DataNode变成死亡结点。一段时间后,对比过程结束。DataSet锁释放,DataNode回归正常工作。
解决
知道问题了就好解决了。我们采取的方式是把getlength操作提取到第二步的线程池的异步磁盘扫描中进行。
部署到线上后,数据对比时间降低到2秒左右。至此,死亡结点问题解决!
后续我们把Patch提交到Hadoop社区HDFS-5341,其中蹩脚的英语语法请大家无视。
原文地址:解决HDFS磁盘扫描导致死亡结点的问题, 感谢原作者分享。

MySQLとSQLiteの主な違いは、設計コンセプトと使用法のシナリオです。1。MySQLは、大規模なアプリケーションとエンタープライズレベルのソリューションに適しており、高性能と高い並行性をサポートしています。 2。SQLiteは、モバイルアプリケーションとデスクトップソフトウェアに適しており、軽量で埋め込みやすいです。

MySQLのインデックスは、データの取得をスピードアップするために使用されるデータベーステーブル内の1つ以上の列の順序付けられた構造です。 1)インデックスは、スキャンされたデータの量を減らすことにより、クエリ速度を改善します。 2)B-Tree Indexは、バランスの取れたツリー構造を使用します。これは、範囲クエリとソートに適しています。 3)CreateIndexステートメントを使用して、createIndexidx_customer_idonorders(customer_id)などのインデックスを作成します。 4)Composite Indexesは、createIndexIDX_CUSTOMER_ORDERONORDERS(Customer_Id、Order_date)などのマルチコラムクエリを最適化できます。 5)説明を使用してクエリ計画を分析し、回避します

MySQLでトランザクションを使用すると、データの一貫性が保証されます。 1)StartTransactionを介してトランザクションを開始し、SQL操作を実行して、コミットまたはロールバックで送信します。 2)SavePointを使用してSave Pointを設定して、部分的なロールバックを許可します。 3)パフォーマンスの最適化の提案には、トランザクション時間の短縮、大規模なクエリの回避、分離レベルの使用が合理的に含まれます。

MySQLの代わりにPostgreSQLが選択されるシナリオには、1)複雑なクエリと高度なSQL関数、2)厳格なデータの整合性と酸コンプライアンス、3)高度な空間関数が必要、4)大規模なデータセットを処理するときに高いパフォーマンスが必要です。 PostgreSQLは、これらの側面でうまく機能し、複雑なデータ処理と高いデータの整合性を必要とするプロジェクトに適しています。

MySQLデータベースのセキュリティは、以下の測定を通じて達成できます。1。ユーザー許可管理:CreateUSERおよびGrantコマンドを通じてアクセス権を厳密に制御します。 2。暗号化された送信:SSL/TLSを構成して、データ送信セキュリティを確保します。 3.データベースのバックアップとリカバリ:MySQLDUMPまたはMySQLPumpを使用して、定期的にデータをバックアップします。 4.高度なセキュリティポリシー:ファイアウォールを使用してアクセスを制限し、監査ロギング操作を有効にします。 5。パフォーマンスの最適化とベストプラクティス:インデックス作成とクエリの最適化と定期的なメンテナンスを通じて、安全性とパフォーマンスの両方を考慮に入れます。

MySQLのパフォーマンスを効果的に監視する方法は? MySqladmin、ShowGlobalStatus、PerconAmonitoring and Management(PMM)、MySQL EnterpriseMonitorなどのツールを使用します。 1. mysqladminを使用して、接続の数を表示します。 2。showglobalstatusを使用して、クエリ番号を表示します。 3.PMMは、詳細なパフォーマンスデータとグラフィカルインターフェイスを提供します。 4.mysqlenterprisemonitorは、豊富な監視機能とアラームメカニズムを提供します。

MySQLとSQLServerの違いは次のとおりです。1)MySQLはオープンソースであり、Webおよび埋め込みシステムに適しています。2)SQLServerはMicrosoftの商用製品であり、エンタープライズレベルのアプリケーションに適しています。ストレージエンジン、パフォーマンスの最適化、アプリケーションシナリオの2つには大きな違いがあります。選択するときは、プロジェクトのサイズと将来のスケーラビリティを考慮する必要があります。

高可用性、高度なセキュリティ、優れた統合を必要とするエンタープライズレベルのアプリケーションシナリオでは、MySQLの代わりにSQLServerを選択する必要があります。 1)SQLServerは、高可用性や高度なセキュリティなどのエンタープライズレベルの機能を提供します。 2)VisualStudioやPowerbiなどのMicrosoftエコシステムと密接に統合されています。 3)SQLSERVERは、パフォーマンスの最適化に優れた機能を果たし、メモリが最適化されたテーブルと列ストレージインデックスをサポートします。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

Dreamweaver Mac版
ビジュアル Web 開発ツール

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ホットトピック









