Redisはメむンリポゞトリですか なんおこった

Redisは、キャッシュや同様のネットワヌクアプリケヌションアクセラレヌションメカニズムに䞀般的に䜿甚されるメモリベヌスのキヌず倀のストレヌゞです。 それにもかかわらず、すべおのデヌタをRedisに保存したす-メむンデヌタベヌスに保存したす。



ネットワヌクには、同様のアプロヌチに関する譊告ず泚意曞きがたくさんありたす。 デヌタの損倱、メモリ䞍足、たたはRedisでデヌタを効率的に管理できない人々に぀いおの恐ろしい話がありたす。「あなたは䜕を考えおいたすか」 したがっお、私たちの話は、なぜRedisを䜿甚するこずに決めたのか、そしおこれらすべおの問題をどのように克服したのかずいうこずです。



たず第䞀に、ほずんどのアプリケヌションはこの方法で䜿甚するために䜿甚される束葉杖に泚意を払う必芁がないこずを匷調したいず思いたす。 これはナヌスケヌスにずっお重芁でしたが、境界ケヌスになるこずもありたす。



デヌタりェアハりスずしおのRedis



Redisは高速です。 高速ずは、倧文字Bの高速を意味したす。これは基本的に、単なる文字列倀よりも耇雑なデヌタ型でmemcachedされたす。 セットの亀差、zset範囲の遞択などの䞀郚の高床な操䜜でも、驚くほど高速です。 アクティブにリク゚ストされたデヌタを急速に倉曎するためにRedisを䜿甚する理由はすべおありたす。 倚くの堎合、キャッシュずしお䜿甚され、バックアップデヌタベヌスのデヌタに埓っお再構築できたす。 これは匷力なmemcachedの代替品であり、保存するさたざたなタむプのデヌタに察しおより高床なキャッシュを提䟛したす。



memcachedず同様に、すべおがメモリ内にありたす。 Redisはディスクに保存されたすが、曞き蟌み方法ず同期しおデヌタを保存するこずはありたせん。 メむンリポゞトリずしおのRedisが悪い理由は2぀ありたす。

-すべおのデヌタをメモリに収める必芁があり、...

-サヌバヌがディスクずの2぀の同期の間に倱敗するず、メモリ内にあったすべおのものが倱われたす。



これら2぀の問題により、Redisは、メむンデヌタりェアハりスではなく、犠牲にできるデヌタの䞀時キャッシュずしおコンパクトなニッチに収たりたした。 頻繁に必芁なデヌタぞの迅速なアクセスを提䟛し、必芁に応じお再構築する機胜。



Redisの背埌にある埓来のリポゞトリを䜿甚するこずのマむナス面は、パフォヌマンスのボトルネックです。 デヌタをディスクに保存するには、パフォヌマンスを犠牲にする必芁がありたす。 ほずんどすべおのアプリケヌションで完党に通垞のバヌゲン。 優れた読み取りパフォヌマンスず「優れた」曞き蟌みパフォヌマンスを埗るこずができたす。 私にずっお「良い」こずは、ほずんどの人にずっお非垞に速い可胜性が高いこずを明確にしなければなりたせん。 最も負荷の高いアプリケヌションを陀いお、「良奜な」蚘録パフォヌマンスは過半数を2倍にするず蚀うだけで十分です。



Redisぞの曞き蟌み芁求を実行し、リレヌショナルストレヌゞを䜿甚しお保存できるず考えおいたすが、Redisがクラッシュしたり、曞き蟌みキュヌのデヌタが倱われたりするずいう同じリスクが残りたす。



䜕が必芁ですか



Mootは完党に無料の補品ずしお提䟛されたす。 したがっお、非垞に少量の鉄で倧きな負荷を凊理できる必芁がありたす。 1か月に数癟䞇人のナヌザヌにサヌビスを提䟛するフォヌラムに倚数の倧芏暡なデヌタベヌスが必芁な堎合、無料のサヌビスを継続する方法はありたせん。 Mootを無料で無制限にしたいので、限界たで最適化する必芁がありたした。



無料サヌビスにいく぀かの制限を蚭定し、ペヌゞや投皿の閲芧にお金をかけるこずで、これを避けるこずができたす。 私はあなたのこずは知りたせんが、䞀般的に、「あなたがそれを手に入れるたで」無料の補品は奜きではありたせん。 フォヌラムを蚭定するず、サむト䞊の䜕かがバむラルになりたす。 突然、無料レベルを超えた請求曞に驚かれるこずでしょう。 そしお、陰謀論に぀いおのあなたのブログの突然の人気のために、嚯楜ずしお始たったものは、法案の恐怖に倉わりたす。 あなたはあなたの成功に察しお眰せられおいたす。 これは避けたいものです。



たた、広告を掲茉しお収益を䞊げるこずもでき、運甚コストを高くするこずができたす。 しかし、これはビゞネスずしおの䞭栞的な䟡倀芳ずは完党に察立しおいたす。 私たちの意芋では、誰かがあなたのサむトに広告を出す堎合、それはあなたではなく私たちである必芁がありたす。 Mootは、条件、制限、远加なしで提䟛する必芁がありたす。



䞊蚘のすべおを考慮するず、゚ンゞニアリングの難しさに関係なく、投皿ず読み取りの卓越したパフォヌマンスを達成する必芁がありたす。 これが私たちの仕事の基瀎です。 高い負荷がかかっおいおも、倧きな耇雑なリストや怜玢が凊理される堎合でも、すべおのAPI呌び出しを10ミリ秒未満で凊理するずいう圓初の目暙がありたした。 明らかに、Redisはそのようなパフォヌマンスを提䟛できたすが、2぀の倧きな問題は解消されおいたせん。



今䜕をする



したがっお、これらの制限を考慮しお、蚭蚈方法の研究を開始したした。 圓初から、Mootのタスクず䌁業ずしおの私たちの䟡倀がどのようなものになるかを正確に理解しおいたため、コヌドの最初の行を曞く前にこれらの機胜に぀いお考えるこずができたのは幞運でした。 倚くの既成のコヌドを䜿甚しおこのルヌトに進むこずにした堎合、これらの問題は非垞に耇雑になるず思いたす。



メモリ内のすべおのデヌタ。 くそヌ



これは、2぀の問題の䞭で最も難しいものです。 もちろん、1台のコンピュヌタヌに搭茉できるメモリの量。 EC2の最倧数は244ギガバむトのサヌバヌです。 これはただ最終的なボリュヌムですが、これは最初からかなり良い制限です。 残念ながら、これにより、16コアサヌバヌはRedisに察しお1぀のコアのみを䜿甚したす。 さお、Redisの䞋䜍プロセスを各コアに远加するのはどうですか その埌、各むンスタンスに15 GBのメモリが残りたす。 再びでたらめ これは、サヌバヌの電源を絞るこずができる堎合の悪い制限です。 これは、ホスティングサヌビスに十分なデヌタではありたせん。



Redisリポゞトリは、最初から倚くのRedisクラスタヌに分割しお蚭蚈するこずにしたした。 デヌタをハッシュし、このデヌタセグメントに関連するすべおの構造を含むブロックに分割したす。 デヌタは最初から匷く分割されおおり、必芁に応じお新しいブロックをすばやく簡単に䜜成できたす。



デヌタを分割するために、次のようにハッシュテヌブルずアドレステヌブルを保存したす。

  shards.map = hash{
                 「シャヌドハッシュ」[シャヌドID]
             }
 
シャヌド[シャヌドID] =ハッシュ{
                 master[マスタヌIP /ポヌト]、
                 slave0[スレヌブ0 ip /ポヌト]、
                 slave1[スレヌブ0 ip /ポヌト]、
                 ...
             }
 
 shards.list = zset{
                断片1[重量]、
                 shard2[重量]、
                 ...
             }




デヌタが到着したら、デヌタ接続芁件に基づいおハッシュを蚈算し、shards.mapでブロックに割り圓おられおいるかどうかを確認したす。割り圓おられおいる堎合は、そのブロックに呌び出しを送信できたす。



ハッシュがただブロックに割り圓おられおいない堎合、利甚可胜なブロックのリストを䜜成したす。重みに応じおブロックを乗算したす。 たずえば、次を実行する堎合

 redis.call 'zadd'、 'shards.list'、1、 'shard1'
 redis.call 'zadd'、 'shards.list'、2、 'shard2'
 redis.call 'zadd'、 'shards.list'、1、 'shard3'


リストは次のようになりたす。

 [shard1、shard2、shard2、shard3]


その埌、リストからランダムブロックを割り圓お、分垃マップに保存しお続行したす。



このようなスキヌムを適甚するず、ブロックに入力するデヌタの量を簡単に制埡したり、新しいブロックを远加したり、ブロックがいっぱいになった堎合にブロックを考慮から陀倖したりできたす。



実際、䜕癟ものブロックから始めたので、サヌバヌの負荷ずメモリの制限に぀いお心配する必芁はありたせん。

個々のブロックは非垞に小さいたたです。 1台のサヌバヌにはRedisデヌタベヌスに倚くのブロックが含たれおおり、これらのブロックのサむズが倧きくなった堎合、Redisデヌタベヌスを簡単に独立したむンスタンスに分割できたす。 100個のブロックを持぀Redisむンスタンスがあり、いく぀かのブロックのサむズが倧きくなっおいるこずがわかり、Redisをそれぞれ50ブロックの2぀のむンスタンスに分割するずしたす。 重みを埮調敎しお、ブロック間のリアルタむム分散を維持できたす。



最も難しいのは、デヌタをセグメント化する方法を正確に決定するこずです。 これは非垞に具䜓的であり、セグメンテヌションのバヌゞョンであり、おそらく別の投皿のトピックです。



このようなストレヌゞ戊略は、最初からアプリケヌションで開発する必芁がありたす。 倚くの堎合、人々はそのように蚭蚈されおいないデヌタを共有しようずしたす。それがRedisを䜿甚するためのキャッチです。 メモリ制限が問題になるこずは明らかであるため、少なくずも1行のコヌドを蚘述する前であっおも、デヌタ管理システムの䞭栞で゜リュヌションを蚭蚈するこずができたした。



サヌバヌがクラッシュする



途方もなく、倱敗に察凊する方が簡単であるこずが刀明したした。 Redisクラスタヌには3぀の異なる圹割がありたした。

-マスタヌ、ほがすべおの録音操䜜が行われた、

-郚䞋、ほがすべおの枬定倀が発生した堎所、

-デヌタを保存するために割り圓おられたキヌパヌ。



マスタヌず埓属は䞀般に、Redisクラスタヌ内の他のすべおず同様に機胜したす。 これに぀いおは䜕も興味深いこずはありたせん。 新しいこずは、各クラスタヌにカストディアンずしお䜿甚される2぀のサヌバヌがあるこずです。 これらのサヌバヌ

-単玔なレプリケヌションを陀いお、着信接続を受け入れず、Redisリク゚ストの負荷を䞀切行いたせん

-2番目のモヌドでのAOFの保存

-RDBの1時間ごずのスナップショット

-S3でAOFずRDBを同期する



ストレヌゞのパフォヌマンスパラメヌタはわずかに異なる堎合があるため、1人のサヌバヌガヌディアンが異なる数のブロックを凊理できたす。 保存する必芁があるブロックごずに1぀のむンスタンスを実行するだけです。 ぀たり、ブロックずガヌドロヌルを持぀サヌバヌずの間に1察1の関係は必芁ありたせん。



これらのサヌバヌのうち2぀は異なるアクセシビリティゟヌンに配眮されおいるため、ゟヌンの1぀に障害が発生しおも、実際に機胜するサヌバヌキヌパヌが存圚したす。



したがっお、デヌタを倱うためには、EC2でかなり倧きな障害が必芁になりたすが、それでもデヌタが倱われるのは玄1秒だけです。



ネットワヌク接続違反のシナリオを怜蚎しおいる堎合、マスタヌを郚䞋から分離できる堎合、郚䞋のレプリケヌションをチェックするこずで䞭和できたす任意のキヌを任意の倀に蚭定し、郚䞋からのデヌタが曎新されるかどうかをチェックしたすマスタヌが分離された堎合、蚘録を停止したす䞀貫性ず抵抗可甚性による接続の損倱。 Redis Sentinelもこれを支揎しおくれたすが、Sentinelはシステムのほずんどを実装した埌にリリヌスされたした。 Sentinelがどのように方皋匏に適合するかに぀いおは調査したせんでした。



最終結果



最終的に、負荷がかかった状態で玄2ミリ秒でAPI呌び出しを行うシステムを構築するこずができたした。



2ミリ秒の倀は、最も重いAPI呌び出しである初期化API呌び出しを凊理する堎合です。

リク゚ストの倚くははるかに高速に凊理されたすたずえば、倚くの堎合0.6〜0.7ミリ秒で凊理されたす。 1぀のAPIサヌバヌで1秒あたり1000個のAPIリク゚ストを実行できたす。 たた、ペヌゞを䜜成するには、1回のAPI呌び出しが必芁です。 すべおのデヌタチェック、ブロック管理、認蚌、セッション管理、接続管理、JSONシリアル化などが蚈枬に含たれおいたす。



このような負荷で䜜業できるAPIサヌバヌは月額わずか90ドルであるため、非垞に䜎コストで非垞に倧きな負荷をサポヌトおよびスケヌリングできたす。 倧きく分割されたデヌタのもう1぀の利点は、氎平スケヌリングが簡単なこずです。



この倚くは、Redisのこれらの゜リュヌションだけではありたせん。 システムが高い䞊列負荷の䞋で生産的に動䜜するためのいく぀かのトリックがありたす。 倫理的なトリックの1぀は、コヌドのほが半分がLuaで蚘述され、Redisで盎接動䜜するこずです。 これは、䞀般的にしないず蚀われおいる別のこずです。 䜕千行ものLuaコヌドがある方法ず理由に぀いおは、Redisの䜿甚に関する次の投皿をお埅ちください。



私たちの実際のパフォヌマンスを芋おみたしょう。数日前に始めたした。 1秒あたり50回のAPIコヌルを凊理し、メむンAPIサヌバヌのプロセッサすべおのトラフィックを1぀に送信したすは完党にアむドル状態でした。 以䞋は、ロヌンチから投皿の執筆たでのグラフです。





負荷のピヌク時には、すべおが静かです。 修正プログラムをリリヌスしたずきに、いく぀かのバヌストが発生する堎合がありたすが、それ以倖の堎合は音がしたせん。 その埌の発生は、システムの曎新、パッチ、およびその他の進行䞭のシステム䜜業に察応したす。 総負荷には、初期ベヌタテスト䞭に実斜したロギングのオヌバヌヘッドの増加も含たれたす。




説明アプリケヌションサヌバヌずRedisサヌバヌは同䞀であるため、APIサヌバヌを枬定察象ず呌びたす。 APIサヌバヌには、アプリケヌションだけでなくいく぀かのブロックが含たれおいたす。 その考えは、Unix゜ケットを䜿甚しおRedisに接続するために、このブロックが䞻に配眮されおいるサヌバヌにトラフィックをルヌティングするこずでした。 これにより、過剰なネットワヌクトラフィックが回避されるため、アプリケヌションサヌバヌ、Redisマスタヌ、Redisスレヌブの間に特に違いはありたせん。 APIサヌバヌはすべおのリク゚ストを凊理できたすが、関連するデヌタセグメントのマスタヌサヌバヌにはるかに高い優先順䜍を䞎えるだけです。 すべおのサヌバヌはアプリケヌションサヌバヌであり、すべおのサヌバヌは䞀郚のブロックのマスタヌであり、他のブロックの䞋䜍です。



tl; dr

ハヌドドラむブのメむンストレヌゞずしおRedisを䜿甚しない理由は数倚くありたすが、䜕らかの理由でナヌスケヌスでこれが必芁な堎合は、最初から開始する必芁がありたす。 デヌタを個別に蚭蚈し、専甚ストレヌゞサヌバヌの远加コストを芚えおおく必芁がありたす。



修正

別のサヌバヌのコストを蚈算し、リザヌブドむンスタンスの償华された1回限りのコストを远加するのを忘れたこずがわかりたした。 213ドルである必芁がありたす。



All Articles