レコードシステムのパフォーマンス・チューニング・プロセス

レビュー質問


ビジネスシナリオの必要性に起因するオンライン環境では、プログラムがまだ通常の4Gのマシンで正しく機能することができますが必要です。8コア16G、マイクロサービスの展開、6つのモジュールの合計元の構成環境。そして、今では4コア4Gデバイス上で正常に実行するために必要な。

問題の一覧


    1. 様々な紛争時にモジュールをマージ、豆のすべての種類が正しくロードされません
    1. 3000〜1ワットのオリジナルイベント処理性能は毎秒、今急に数百に低下しました。
    1. 損失事象の現象だけでなく、より深刻なの損失があります
    1. 私たちは、システムキャッシュをほぼ-m後になくなって見つけることができるよりも、空きメモリが上昇し続けていることがわかった(ほとんどなくなっている、実際には、100Mの残りについては、削減されることはありません)

トラブルシューティング

1.コード違反


  • パッケージ名の競合。異なるモジュールの設計上のパッケージ名を重複
  • クラス名の競合。@Configuration @Bean @Controller @Service @RepositoryBeanインスタンス名などのメモが指定されていません。

2.イベント処理性能が遅いです


次のように、従来のプロセスです。

项目采用SpringBoot构建,引入 spring-boot-stater-redis
1. 通过HTTP接收到异步事件,存储到Redis;
2. 存储的同时,将事件通过Redis的发布订阅发送到不同的处理单元进行处理;
3. 每个事件处理单元通过Redis订阅,然后处理事件;
4. 起一个定时器,每秒钟从Redis中查询一个时间窗口的事件,构建索引,然后bulkIndex到ES
复制代码

2.1問題の発見

1. Redis的订阅发布,内部会维护一个container线程,此线程会一直存在;
2. 每次订阅,都会产生一个新的前缀为RedisListeningContainer-的线程处理;
3. 通过jvisualvm.exe 查看线程数,该类线程数一直在飙升
复制代码

2.2問題を突き止めます

2.2.1 Redisのは、質問を投稿する購読します

次のようにしているプログラムを実装します。

@Bean
RedisMessageListenerContainer manageContainer(
        RedisConnectionFactory factory, MessageListener listener) {
  RedisMessageListenerContainer manageContainer = 
                    new RedisMessageListenerContainer ();
  manageContainer.setConnectionFactory(factory);
  // manageContainer.setTaskExecutor();
}
复制代码

コードは、実際のコードが提供されていない行ではない、とコメントしていますtaskExecutor

  • 照会春-redis.xsdに関するlistener-containerデフォルトの説明task-executorsubscription-task-executor使用をSimpleAsyncTaskExecutor
  • ソースコード内の場所

RedisMessageListenerContainer.class

...
protected TaskExecutor createDefaultTaskExecutor() {
    String threadNamePrefix = (beanName != null ? beanName + "-" :
    DEFAULT_THREAD_NAME_PREFIX) ;
    return new SimpleAsyncTaskExecutor(threadNamePrefix);
}
...
复制代码

SimpleAsyncTaskExecutor.class

...
protected void doExecute(Runnable task) {
    Thread thread = 
        (this.threadFactory != null 
            ? this.threadFactory,newThread(task) 
            : createThread(task));
    thread.start();
}
...
复制代码
  • SimpleAsyncTaskExecutorexecute()メソッドは、非常に恥知らずでnew Thread()呼び出しthread.start()たタスクを実行するには、

2.2.2イベント処理はより多くのスレッドもOOM、その結果、時間のかかる操作であります

2.3問題解決

問題の原因を見つけ、三つの主要なソリューションがあります。

  • 設定manageContainer.setTaskExecutor();、独自のスレッドプールを作成することを選択します。

  • 賛成でパブリケーション・サブスクリプションの一部を削除しSpring提供オブザーバーモードを、イベント処理のほとんどのシーンは、これは出版物によって達成されます。SpringUtils.getApplicationContext() .publihEvent(newEventOperation(eventList));

  • 使用してRector効率的な非同期イベント処理を実現するためのモデルを。

创建了2个线程组(参考netty的底层实现):
1. 一个用于处理事件接收 “event-recv-executor-”
    coreSize = N * 2,CPU密集型
2. 一个用于事件的异步处理 “event-task-executor-” 
    coreSize = N / 0.1,IO密集型
复制代码
事件处理逻辑
@Override
public void onApplicationEvent (EventOperation event) {
    eventTaskExecutor.execute(() -> {
        doDealEventOperation(event);
    });
}
复制代码

3.イベント損失


次のように、従来のプロセスです。

项目采用SpringBoot构建,引入 spring-boot-stater-redis
1. 后台维护了一个定时器,每秒钟从Redis中查询一个时间窗口的事件
复制代码

3.1問題の発見

在后台定位日志输出,正常情况下,应该是每秒钟执行一次定时,
但实际是,系统并不保证一定能每隔1S执行一次,
由于系统中线程比较多,CPU的切换频繁,
导致定时有可能1S执行几次或者每隔几秒执行一次
复制代码

3.2問題を突き止めます

3.2.1定期的なタスクの信頼性が低いです

由于定时并无法保证执行,而定时任务获取事件时,是按照时间窗口截取,
通过redisTemplate.opsForZSet().rangeByScore(key, minScore, maxScore)实现,
势必会造成有数据无法被加载到程序中,而一直保存在Redis中,无法获取,也无法删除
复制代码

3.3問題解決

問題の原因を見つけ、二つの主要なソリューションがあります。

  • フォールトトレランスを増やし、変更1MINで区切られた、元は離れて時間ウィンドウ1Sで、時間ウィンドウを広げます[一時的な解決策を、極端な場合には、まだ問題が発生することがあり]。

  • 使用MQの消費量を、この方法は、低マシンで使用することができ、高いクラスタ構成に追加のMQサーバーの展開、不適切な設定が必要です。

  • 使用して、ブロッキングキュー、使用Lock.newCondition()または最も一般的なネットワーク監視モードをwhile()することができます。

質問は三番目の形式で使用されています。別のスレッドから、モニターを遮断します。

1. 事件接收后,直接塞到一个BlockingQueue中;
2. 当BlockingQueue有数据时,While循环不阻塞,逐条读取队列中的信息;
3. 每隔1000条数据,或者每隔1S,将数据写入ES,并分发其他处理流程
复制代码

4.システムキャッシュは絶えず上昇しています


4Gのマシンでは、いくつかの時間のための入札プロセスの後に見つかった、システムキャッシュの成長はほぼ完全に占有最後に、非常に高速です。

大概每秒钟10M的涨幅
复制代码

4.1問題の発見

1. 因为对于ES的了解,插入数据时,先写缓存,后fsync到磁盘上,因此怀疑ES可能存在问题;
2. 项目中日志使用log4j2不当:
    * 日志输出过多,
    * 日志没有加判断:if (log.isInfoEnabled()) 
    * 日志文件append过大,没有按照大小切分等(本项目此问题之前已解决)
复制代码

4.2問題を突き止めます

4.2.1 ES挿入機構

经过隔段分析,将有可能出现问题的地方,分别屏蔽后,进行测试。
最终定位到,在ES批量写入数据时,才会出现cache大量增长的现象
复制代码

4.3問題解決

コマンドメモリに確認してくださいfree -m

  • buffer:のようにbuffer cacheメモリ、ブロックデバイスは、バッファを読み書きします
  • cached表現page cache的内存文件系统的cache
  • キャッシュされた値が大きい場合は、ライブドキュメントの数は、キャッシュロット

ES運用データのメカニズムの基礎となります

データが書き込まれると、ESメモリは、あまりにも多くの小さなファイルは、(ES自体はインデックス時間の小さな多数のファイルが作成されます)ので、ゆっくりと上昇し、linux dentryかつinode cache増加します。参照することができます:問題を特定するためにESメモリは上昇し続け

実際には、この問題は完全に解決が、ある程度のパフォーマンスをキャッシュと引き換えにされていません。

    1. メモリ優先スラブリリースを改善するために、システムパラメータを変更します。
echo 10000 > /proc/sys/vm/vfs_cache_pressure;
复制代码
    1. ESは、設定パラメータを変更します
## 这些参数是之前优化的
threadpool.bulk.type: fixed
threadpool.bulk.min: 10
threadpool.bulk.max: 10
threadpool.bulk.queue_size: 2000

threadpool.index.type: fixed
threadpool.index.size: 100
threadpool.index.queue_size: 1000

index.max_result_window: 1000000
index.query.bool.max_clause_count: 1024000


# 以下的参数为本次优化中添加的:

# 设置ES最大缓存数据条数和缓存失效时间
index.cache.field.max_size: 20000
index.cache.field.expire: 1m

# 当内存不足时,对查询结果数据缓存进行回收
index.cache.field.type: soft

# 当内存达到一定比例时,触发GC。默认为JVM的70%[内存使用最大值]
#indices.breaker.total.limit: 70%

# 用于fielddata缓存的内存数量,
# 主要用于当使用排序操作时,ES会将一些热点数据加载到内存中来提供客户端访问
indices.fielddata.cache.expire: 20m
indices.fielddata.cache.size: 10%

# 一个节点索引缓冲区的大小[max 默认无限制]
#indices.memory.index_buffer_size: 10%
#indices.memory.min_index_buffer_size: 48M
#indices.memory.max_index_buffer_size: 100M

# 执行数据过滤时的数据缓存,默认为10%
#indices.cache.filter.size: 10%
#indices.cache.filter.expire: 20m

# 当tranlog的大小达到此值时,会进行一次flush操作,默认是512M
index.translog.flush_threshold_size: 100m

# 在指定时间间隔内如果没有进行进行flush操作,会进行一次强制的flush操作,默认是30分钟
index.translog.flush_threshold_period: 1m

# 多长时间进行一次的磁盘操作,默认是5S
index.gateway.local.sync: 1s
复制代码

回顧


  • この調整プロセスのために、主方向又はコード、すなわちコード不適切な使用、または悪いと見なさで結果を修正します
  • 第二に、基礎となるESの実装メカニズムは、特定の問題を対象とする、非常に精通していません。
  • 最適化プロセスは、GCのポジショニング、Linuxのような基本的なシステムパラメータの設定を必要とします
  • 各送信は、新しいスレッドになるように、HTTPを使用してログ送信以来。IOのオーバーヘッドが比較的大きい、フォローアップが置き換えられみなされる長いリンク

添付ファイル:

エラーがテキストコンテンツに記述されている場合、または、問題の明確な説明は、あなたが、私にメールを送ることができますが存在しない[email protected]他の質問がある場合は、あなたが私に連絡することができますし、私たちが一緒に議論します。

  • 私は一緒に成長し、一緒に進歩をしたいと思います。

おすすめ

転載: juejin.im/post/5d6740d7f265da03986c04ec