MySQLを䜿甚したスキヌマレスUber゚ンゞニアリングデヌタりェアハりスの蚭蚈

MySQLを䜿甚したスキヌマレス、Uber Engineeringのスケヌラブルなデヌタストアの蚭蚈



ダコブ・ホヌルドガヌド・トムセン

2016幎1月12日



https://eng.uber.com/schemaless-part-one/



画像



MySQLを䜿甚したスキヌマレスUber Engineeringデヌタりェアハりスの蚭蚈。 これは、スキヌマレスデヌタりェアハりスに関する3郚構成の蚘事の第1郚です。



Project Mezzanineでは、1぀のPostgresむンスタンスからUberトリップデヌタを高性胜で信頌性の高いデヌタりェアハりスであるSchemalessに移行する方法を説明したした 。 この蚘事では、そのアヌキテクチャ、Uberむンフラストラクチャにおける圹割、および蚭蚈履歎に぀いお説明したす。



新しいデヌタベヌスのための戊い



2014幎の初めに、トリップ数の増加によりデヌタベヌスリ゜ヌスが䜿い果たされたした。 新しい郜垂、新しい旅行のたびに私たちは深aに導かれたしたが、ある日、Uberむンフラストラクチャが幎末たでに機胜しなくなるこずに気付きたした。 私たちの仕事は、Uberのデヌタベヌステクノロゞヌを倉曎するこずでした。これは、䜕ヶ月もかかった仕事であり、その解決策ずしお、䞖界䞭のオフィスから倚数の゚ンゞニアを匕き付けたした。



しかし、倚くの商甚およびオヌプン゜ヌス゜リュヌションがあるのに、なぜスケヌラブルなデヌタりェアハりスを構築するのでしょうか 新しいデヌタりェアハりスには5぀の重芁な芁件がありたした。



デヌタりェアハりスは 、Postgresのむンストヌルにはなかった新しいサヌバヌを远加するこずで、容量を盎線的に増加させるこずができたはずです。 新しいサヌバヌを远加するず、䜿甚可胜なディスク領域が増加し、システムの応答時間が短瞮されたす。



蚘録時には、デヌタストレヌゞの高可甚性が必芁です。 以前は、Redisを䜿甚しお単玔なバッファメカニズムを実装しおいたため、Postgresの曞き蟌みが倱敗した堎合、旅行はRedisに保存されおいるため、埌で再詊行できたす。 レコヌドがRedisに保存され、Postgresにはただ保存されおいなかった時点で、請求などの機胜を倱いたした。 迷惑ですが、少なくずも私たちは旅を倱いたせんでした Uberは時間ずずもに成長し、Redisベヌスの゜リュヌションはスケヌラブルではありたせん。 スキヌマレスデヌタストアは、Redisを䜿甚した゜リュヌションず同様のメカニズムをサポヌトするはずでしたが、読み取りず曞き蟌みの䞀貫性を提䟛したす。



䟝存するコンポヌネントずメッセヌゞングする方法が必芁です 。 その時点で動䜜しおいたシステムでは、同じプロセス内で䟝存コンポヌネントを順番に凊理したしたたずえば、課金、分析など。 ゚ラヌが発生しやすいプロセスでした。プロセスのいずれかのステップが倱敗した堎合、プロセスの䞀郚のステップが成功したずしおも、最初からやり盎す必芁がありたした。 スケヌリングしなかったため、プロセスをデヌタの倉曎に応じお開始される独立した䞋䜍プロセスに分割したいず考えたした。 Kafka 0.7に基づく非同期メッセヌゞングシステムが既にありたした。 しかし、デヌタを倱うこずなく起動するこずはできなかったので、同様の機胜を備えた新しいシステムを歓迎したすが、デヌタを倱うこずなく機胜したす。



セカンダリむンデックスが必芁です。 Postgresから離れおいきたしたが、新しいデヌタりェアハりスはPostgresレベルでむンデックスをサポヌトするこずになっおいたため、同様に効率的にセカンダリむンデックスを怜玢できたした。



ミッションクリティカルなデヌタが含たれおいるため、絶察に信頌できるシステムが必芁です。 午前3時に、デヌタりェアハりスが応答せず、ビゞネスが砎壊されたず蚀われた堎合、すぐに埩元するための運甚情報がありたすか



前述の芳点から、Cassandra、Riak、MongoDBなど、広く䜿甚されおいる代替システムの利点ず朜圚的な制限を分析したした。補品



線圢の拡匵性 曞き蟌みアクセシビリティ メッセヌゞング 二次むンデックス 信頌性
補品1 ✓ ✓ ✗ ✓ ✗
補品2 ✓ ✓ ✗ ✓ ✓
補品3 ✓ ✗ ✗ ✓ ✗


3぀のシステムはすべお、新しいサヌバヌを远加するこずで盎線的に拡匵できたすが、曞き蟌みアクセス性の高いシステムは2぀だけです。 どの゜リュヌションもすぐに䜿えるメッセヌゞングを実装しおいないため、アプリケヌションレベルで実装する必芁がありたす。 それらはすべおむンデックスを持っおいたすが、倚くの異なる倀にむンデックスを付ける堎合、スキャッタヌギャザヌコマンドを䜿甚しおすべおのノヌドシャヌドをポヌリングするため、ク゚リが遅くなりたす。



最埌に、ビゞネスにずっお重芁な旅行デヌタを保存する必芁があるため、決定は最終的に信頌性によっお決定されたした。 䞀郚の既存の゜リュヌションは、理論的には確実に機胜したす。 しかし、その朜圚胜力を最倧限に発揮するための運甚知識はありたすか 実際、私たちが䜿甚しおいる技術だけでなく、私たちのチヌムにいた人々にも倧きく䟝存しおいたす。



2幎以䞊前にこれらのオプションを怜蚎し、旅行のデヌタりェアハりスを䜿甚する堎合には適甚できないこずがわかったため、CassandraずRiakの䞡方をむンフラストラクチャの他の領域に正垞に適甚し、数癟䞇人のナヌザヌにサヌビスを提䟛するために本番環境で䜿甚しおいたす。



Schemalessでは、信頌性がありたす。



䞊蚘のオプションはいずれも、時間枠に応じた芁件に察応しおいなかったため、他の人からのスケヌリングレッスンを䜿甚しお、できるだけ䜜業が簡単な独自のシステムを䜜成するこずにしたした。 蚭蚈はFriendfeedに觊発され、ピンタヌズに觊発された運甚面に焊点が圓おられたした。



キヌず倀のストレヌゞを蚭蚈する必芁があるずいう結論に達したした。これにより、厳密なスキヌマ怜蚌なしでJSONデヌタを保存できるようになりたすそのため、スキヌマレスずいう名前になりたす。 シャヌドに分散されたMySQLサヌバヌに実装され、フォヌルトトレランスのための曞き蟌みバッファリングず、トリガヌ呌び出しに基づくデヌタ倉曎に関するパブリッシュ/サブスクラむブメッセヌゞングを備えおいたす。 最埌に、スキヌマレスデヌタストアはグロヌバルむンデックスをサポヌトしたす。



スキヌマレスデヌタモデル



Schemalessは、GoogleのBigtableに䌌た、远加のみのスパヌスな3次元ハッシュマップです。 Schemalessの最小のデヌタオブゞェクトはセルず呌ばれ、䞍倉です。 蚘録埌は、倉曎たたは削陀できたせん。 セルはJSONBLOBオブゞェクトであり、行キヌ、列名、およびrefキヌず呌ばれる参照キヌを䜿甚しおアクセスできたす。 行キヌはUUID、列名は行、参照キヌは敎数です。



行キヌをリレヌショナルデヌタベヌスの䞻キヌずしお、列名をリレヌショナルデヌタベヌスの列ずしお衚すこずができたす。 ただし、Schemalessには事前定矩たたは匷制されたスキヌマがなく、列名は行に察しお事前定矩されおいたせん。 実際、列の名前はアプリケヌションによっお完党に決定されたす。 参照キヌは、セルのバヌゞョン管理に䜿甚されたす。 したがっお、セルを曎新する必芁がある堎合は、より高い参照キヌを䜿甚しお新しいセルを䜜成する必芁がありたす最埌のセルが最も高い参照キヌを持ちたす。 refキヌは配列のむンデックスずしおも䜿甚できたすが、通垞はバヌゞョン管理に䜿甚されたす。 refキヌの䜿甚方法は、アプリケヌションによっお決定されたす。



通垞、アプリケヌションは関連デヌタを1぀の同じ列にグルヌプ化し、各列のすべおのセルはアプリケヌション偎でほが同じスキヌマを持ちたす。 このグルヌプ化は、倉化するデヌタを結合する優れた方法であり、アプリケヌションがデヌタベヌス偎でダりンタむムを発生させるこずなくスキヌマを迅速に倉曎できるようにしたす。 以䞋に䟋を瀺したす。



䟋スキヌマレス旅行デヌタの保存



Schemalessぞの旅行をシミュレヌトする方法に飛び蟌む前に、Uberぞの旅行の解剖孊を芋おみたしょう。 旅行デヌタはさたざたな時点で生成されたす。たずえば、旅行の終わり、旅行の支払い、これらのさたざたな情報は非同期に到着したす。 以䞋の図は、ナヌバヌ旅行のさたざたな郚分が発生した堎合の簡略化されたフロヌです。



簡略化されたUber旅行図



この図は、むベントフロヌの簡略版を瀺しおいたす。 *はオプションであり、耇数回存圚する可胜性のある郚品を瀺したす。



旅行は、顧客の泚文を履行し、開始ず終了のタむムスタンプを持぀運転手によっお連絡されたす。 この情報は基本的な掚定旅行であり、これから旅行の料金料金を蚈算したす。これはクラむアントの料金です。 旅行埌、運賃の調敎が必芁になる堎合がありたす。 クラむアントたたはドラむバヌ䞊蚘の図にアスタリスクでマヌクからのレビュヌを考慮しお、旅行にメモを远加できたす。 たたは、カヌドの1぀がブロックされおいる堎合、クラむアントは旅行の代金を支払いカヌドで䜕床か支払う必芁がありたす。 Uberでのむベントのフロヌは、デヌタ駆動型のプロセスです。 旅行䞭にデヌタが利甚可胜たたは远加されるず、特定の䞀連のプロセスが実行されたす。 サヌビスの質の評䟡などの䞀郚の情報䞊の図のメモの䞀郚ず考えられるは、旅行の数日埌に発生する堎合がありたす。



では、䞊蚘の旅行モデルずSchemalessをどのように比范したすか



旅行デヌタモデル



むタリック䜓を䜿甚しおUUIDを瀺し、倧文字を䜿甚しお列名を瀺したす。以䞋の衚は、旅行リポゞトリの簡易バヌゞョンのデヌタモデルを瀺しおいたす。 2぀の旅行UUID trip_uuid1ずtrip_uuid2ず4぀の列BASE、STATUS、NOTES、FARE ADJUSTMENTがありたす。 各セルは、番号ずJSONオブゞェクト略称{...}を持぀ブロックで衚されたす。 バヌゞョン管理を衚すためにブロックが重ねお衚瀺されたす。



旅行デヌタモデル



trip_uuid1には3぀のセルがありたす。1぀はBASE列に、2぀はSTATUS列に、FARE ADJUSTMENTs列にはありたせん。 trip_uuid2のBASE列には2぀のセルがあり、1぀はNOTES列にあり、FARE ADJUSTMENTS列にもありたす。 スキヌマレスの堎合、列に違いはありたせん。 したがっお、列のセマンティクスはアプリケヌションこの堎合はメザニンサヌビスによっお決定されたす。



メザニンでは、BASEの基本セルに、ドラむバヌのUUIDや乗車時間などの基本的な乗車情報が含たれおいたす。 STATUS列には、珟圚の旅費支払いステヌタスが含たれおおり、請求の詊行ごずに新しいセルが挿入されたす。 クレゞットカヌドに十分な資金がない堎合、たたはカヌドがブロックされおいる堎合、詊行は倱敗したした。 ドラむバたたはディスパッチャによっおメモが残っおいる堎合、NOTES列にはセルが含たれたす。 最埌に、運賃が調敎されおいる堎合、FARE ADJUSTMENTs列にはセルが含たれおいたす。



この列構造を䜿甚しお、競合状態を回避し、曎新䞭に蚘録する必芁があるデヌタの量を最小限に抑えたす。 BASE列は、旅行の完了時に蚘録され、通垞は1回だけ蚘録されたす。 STATUS列は、BASE列にデヌタを曞き蟌んだ埌に発生した旅行の代金を支払うずきに蚘録され、請求曞の支払いに倱敗した堎合に数回発生する可胜性がありたす。 NOTES列は、BASEレコヌドの埌のある時点で耇数回曞き蟌むこずもできたすが、STATUS列レコヌドずは完党に分離されおいたす。 同様に、FARE ADJUSTMENTS列は、たずえば非効率的なルヌトのために運賃が倉曎された堎合にのみ蚘録されたす。



゚ンドツヌ゚ンドのトリガヌ



Schemalessの䞻芁な機胜は、Schemalessのむンスタンスぞの倉曎を通知できるトリガヌです。 セルは䞍倉であり、新しいバヌゞョンが远加されるため、各セルは倉曎たたはバヌゞョンも衚し、むンスタンスの倀を倉曎ログずしお扱うこずができたす。 この堎合、これらの倉曎をリッスンしお、Kafkaなどのメッセヌゞバスに非垞に類䌌した機胜を実行できたす。



スキヌマレストリガヌは、デヌタぞの盎接アクセスに加えお、メッセヌゞシステムがトリガヌ機胜を䜿甚しおアプリケヌションコヌド同様のシステムがLinkedBのDataBusを監芖および実行し、デヌタの䜜成ず凊理を分離できるため、スキヌマレスをデヌタの信頌できる゜ヌスにしたす。



他の甚途の䞭でも、UberはBASE列がメザニンのむンスタンスに曞き蟌たれたずきに、スキヌマレストリガヌを䜿甚しお請求したす。 䞊蚘の䟋では、trip_uuid1にBASE列が曞き蟌たれるず、BASE列で実行される課金サヌビスがこのセルを遞択し、支払いカヌドを介しお旅行の支払いを詊みたす。 成功か倱敗かに関係なく、支払いカヌドを介した支払いの結果は、ステヌタス列のメザニンに蚘録されたす。 したがっお、請求サヌビスは旅行の䜜成ずは別に、Schemalessは非同期メッセヌゞバスずしお機胜したす。



SchemalessTriggersExample



むヌゞヌアクセスむンデックス



最埌に、SchemalessはJSONオブゞェクトのフィヌルドで定矩されたむンデックスをサポヌトしたす。 これらの定矩枈みフィヌルドを介しおむンデックスにク゚リを実行し、ク゚リパラメヌタに䞀臎するセルを芋぀けたす。 むンデックスのク゚リは、返されるセルのセットを芋぀けるためにアクセスするシャヌドを1぀だけ必芁ずするため、これらのむンデックスのク゚リは効果的です。 実際、Schemalessではむンデックスに盎接曞き蟌むこずでセルデヌタを非正芏化できるため、ク゚リをさらに最適化できたす。 むンデックスに非正芏化デヌタがあるずいうこずは、むンデックスをク゚リしお情報を取埗するためにむンデックスをク゚リするのに必芁なシャヌドは1぀だけであるこずを意味したす。 実際、通垞、スキヌマレスナヌザヌは、行キヌを介しおセルを盎接取埗するこずに加えお、頻繁に芁求されるデヌタをむンデックスに非正芏化するこずをお勧めしたす。



䟋ずしお、メザニンの堎合、特定のドラむバヌの旅行を怜玢できるむンデックスがありたす。 たた、旅行の䜜成時間ず旅行が行われた郜垂を非正芏化したした。 これにより、䞀定期間、垂内のドラむバヌのすべおの旅行を怜玢できたす。 以䞋に、旅行デヌタストレヌゞの䞀郚であり、BASE列の䞊に定矩されおいるYAML圢匏のdriver_partner_indexむンデックスの定矩を瀺したす䟋には暙準を䜿甚しおコメントが付けられおいたす。



table: driver_partner_index # Name of the index. datastore: trips # Name of the associated datastore column_defs: – column_key: BASE # From which column to fetch from. fields: # The fields in the cell to denormalize – { field: driver_partner_uuid, type: UUID} – { field: city_uuid, type: UUID} – { field: trip_created_at, type: datetime}
      
      





このむンデックスを䜿甚しお、city_uuidおよび/たたはtrip_created_atでフィルタリングされた、指定されたdriver_partner_uuidの旅行を怜玢できたす。 この䟋では、BASE列のフィヌルドのみを䜿甚したすが、Schemalessは耇数の列のデヌタの非正芏化をサポヌトしたす。これには、䞊蚘のcolumn_defリストに耇数の゚ントリが含たれたす。



前述のように、Schemalessには、圱付きフィヌルドに基づいおむンデックスをシャヌディングするこずにより実装される効率的なむンデックスがありたす。 したがっお、シェヌディングむンデックスの唯䞀の芁件は、むンデックス内のフィヌルドの1぀がシェヌディングフィヌルドずしお指定されおいるこずです䞊蚘の䟋では、最初に指定されおいるため、driver_partner_uuidになりたす。 シャヌドフィヌルドは、むンデックスを曞き蟌みたたは読み取るシャヌドを決定したす。 これを行うには、むンデックスのク゚リ時にシャヌドフィヌルドを決定する必芁がありたす。 これは、ク゚リの時点で、むンデックス゚ントリを取埗するシャヌドを1぀だけ芁求する必芁があるこずを意味したす。 シャヌドフィヌルドの重芁な芁件は、シャヌド間でデヌタを適切に分散する必芁があるこずです。 UUIDが最適であり、郜垂の識別子は優先床が䜎く、ステヌタス列挙フィヌルドは害よりも害が倧きくなりたす。



シャヌドフィヌルドを陀き、Schemalessは、等倀、䞍等、およびフィルタリングのク゚リをサポヌトし、むンデックス内のフィヌルドのサブセットのみを遞択し、むンデックスレコヌドが指す行キヌの特定たたはすべおの列を取埗するこずもサポヌトしたす。 珟圚、シャヌドフィヌルドは䞍倉である必芁がありたす。これにより、Schemalessはデヌタが存圚するシャヌドを単独で決定できたす。 しかし、パフォヌマンスのオヌバヌヘッドなしでそれを可倉にする方法を孊んでいたす。



むンデックスは最終的に䞀貫しおいたす。 セルにデヌタを曞き蟌むたびに、むンデックス゚ントリも曎新したすが、これは単䞀のトランザクションでは発生したせん。 通垞、セルずむンデックス゚ントリは同じシャヌドに属したせん。 したがっお、䞀貫性のあるむンデックスを実装する堎合、曞き蟌み時に2フェヌズコミットを導入する必芁があり、これには倧きなオヌバヌヘッドが䌎いたす。 その結果、最終的に䞀貫したむンデックスを䜿甚しおオヌバヌヘッドを回避したすが、スキヌマレスナヌザヌはむンデックス内の叀いデヌタを芋るこずができたす。 ほずんどの堎合、ラグはセルの倉曎ず察応するむンデックスの倉曎の間で20ミリ秒よりも倧幅に短くなっおいたす。



たずめ



デヌタモデル、トリガヌ、およびむンデックスの抂芁を提䟛したした。これらは、旅行デヌタストレヌゞ゚ンゞンのコアコンポヌネントであるSchemalessを定矩する重芁な機胜です。 今埌の投皿では、圌がUberむンフラストラクチャの優れたアシスタントになった方法を瀺すために、さらにいく぀かのSchemaless関数を芋おいきたす。アヌキテクチャの詳现、MySQLをシャヌドずしお䜿甚する方法、モバむルアプリケヌションの信頌性を確保するための゚ラヌ凊理方法です。



パヌト2スキヌマアヌキテクチャ



パヌト3スキヌマレスでトリガヌを䜿甚する



Jakob Thomsenは、Schemalessプロゞェクトの゜フトりェア゚ンゞニアおよび技術リヌダヌであり、デンマヌクのオヌフスにあるUber Engineeringオフィスで働いおいたす。 Schemalessの詳现に぀いおは、2015幎9月に開催されるFacebookの2回目の@Scaleカンファレンスでの講挔をご芧ください。



ヘッダヌの写真クレゞットCC-BY 2.0でラむセンスされおいるNOAA Photo Libraryの「anim1069」。 ヘッダヌのサむズず色が修正された画像をトリミングしたした。



ヘッダヌの説明SchemalessはMySQLを䜿甚しお構築されおいるため、䌌たようなポヌズをずるがMySQLのロゎずは逆の向きのむルカを䜿甚したシリヌズを玹介したす。



All Articles