ピーク時の毎分100万件のデータ要求をGOで処理する方法

2933 ワード

最近、goで毎分百万件のデータ要求を処理する文章を見ました.
原文住所:http://marcio.io/2015/07/handling-1-million-requests-per-minute-with-golang/
翻訳先:https://www.jianshu.com/p/21de03ac682c
 
ここで著者らは,ピーク時の同時データ要求を処理するために,3つのバージョンの処理方式を用いたが,以下は自分の理解である.
1つ目の方法は簡単です.goのコヒーレント処理要求を使って、各要求がデータアップロードであるため、1つのコヒーレント処理を開きます.
タスクは、一定の時間と資源の消費があり、ピーク時の要求が突然増加して毎分百万件に達したとき、携帯電話の爆発、システムの崩壊を避けられない.
 
第2の方法はchannelでタスクキューを作り、タスクキューに追加するように要求した.簡単な生産者消費者モデルだが、この方法では治標が治らず、ピーク時にはタスクキューの長さが同じように爆発し、メモリが足りないため、あまり適切ではない.
3つ目の方法は少し面白いです.ここに完全なコードを貼って、理解を助けます.
package main



import (

"fmt"

"time"

   "runtime"

)





var (

   //       

   MaxWorker = 10

)





//    

type Payload struct {

   Num int

   Test     string

}





//      

type Job struct {

   Payload Payload

}





//    channal

var JobQueue chan Job





//          

type Worker struct {

   WorkerPool chan chan Job //    --               channal

   JobChannel chan Job      //                      

   quit       chan bool     //    

   no         int           //  

}



//     

func (w Worker) Stop() {

   go func() {

      w.quit 

この方法は簡単に言えば、1つの2段階channelを1つのタスクキュープールとして使用し、キュープールに複数のタスクキューを格納し、1つのタスクを1つ追加した後、1つのタスクキューに参加し、各タスクキューに1つのコヒーレント処理データアップロードタスクを開き、基本的なプロセスは以下の図に示す.
 
如何用GO处理高峰期每分钟100万条数据请求_第1张图片        
この方法は、ワークフローの処理に10個のワークフローしかなく、ワークプールに10個のタスクキューしかなく、各タスクキューに1個のタスクしか保存されていないため、キュー長が爆発する問題もありませんが、この方法にも問題があります.つまり、ワークプールにタスクキューが空いていない場合、新しく来たタスクは、アクセスピークが長すぎるか、タスク処理に時間がかかると、タスクキューを待つスレッドが急激に増加し、システムメモリがクラッシュする可能性があります.この方式の利点は、タスクキューを待つコヒーレンスが軽量レベルのコヒーレンスであり、各コヒーレンスが消費するメモリリソースが少ないため、ピーク時の毎分百万件のデータ要求を処理するだけであれば、可能であり、ピーク時に各タスクを軽量レベルのコヒーレンスにキャッシュすることに相当し、ピーク時を過ぎると軽量レベルのコヒーレンスが減少し、コモンシップ爆発によるメモリクラッシュは発生しません.しかし、毎分100万件のデータ要求が常態であれば、メモリがクラッシュするに違いありません.
解決方法は2つあります.
     1.データベース・レベルのキャッシュはタスク・キューとして使用され、ハード・ディスク(HDD)はメモリよりも大きく、安価ですが、この方法では遅延が大きくなります.
     2.機械をプラスして負荷の均衡をして、高い合併がなくて1台の機械をプラスして解決できないので、もしあれば、もっと何台か追加します.
また、第1の方法と第3の方法の良し悪しは、各タスクの処理時間とワークプール内のタスクキューの数に依存し、各タスクを処理するのに5秒かかる例として、各タスクに1つの協程処理が必要である場合、第1のタスクを処理した後、システムのメモリ占有量は安定します.新しく開いた協程は終わりの協程速度と同じなので、池のように入水速度や出水速度が速いので、もちろんメモリオーバーフローの問題はありません.3つ目の方法は、ワークプールに10個のタスクキューしかタスクを処理していないため、ブロック待ちのコモンシップが多すぎるため、最終的にはシステムメモリがクラッシュします.しかし、この時点でワークプール内のタスクキュー数を1000個に増やすと、タスク処理速度が著しく増加し、システムのクラッシュは発生しません.さらに、各タスク処理に50秒かかる例を挙げると、1つ目の方法は、継続的なオープンワークのため、最初のタスク処理が完了するのを待たずにメモリがクラッシュします.しかし、第3の方法では、タスクキューを1000個に追加し、各タスクを処理するのに50秒かかってもメモリは担ぐことができ、タスクを処理する協程も1000個に増えたので、メモリをよりバランスよく割り当てることができます.
したがって、第3の方法の設計はより合理的で、拡張性がより強い.