Microsoft Azure Storageのデヌタぞの同時アクセスの組織





珟代のWebアプリケヌションでは、耇数のナヌザヌが同じデヌタを同時に操䜜する堎合に状況がしばしば発生したす。



各ナヌザヌのアクションを確実に成功させるために、アプリケヌション開発者は、特にナヌザヌのグルヌプによるデヌタの同時凊理が本圓に必芁な堎合、そのようなシナリオの凊理ず実装を慎重に怜蚎する必芁がありたす。



ほずんどの堎合、開発者はデヌタぞの同時アクセスを管理するために次の3぀の戊略を䜿甚したす。



  1. 楜芳的䞊行性



    アプリケヌションは、最埌にアクセスされおからの倉曎をチェックした埌にのみデヌタを曎新したす。



    たずえば、2人のナヌザヌが同じWikiペヌゞを衚瀺しおいるずきに、同時にそれを曎新するこずにしたした。



    この堎合、wikiプラットフォヌムは、2番目のナヌザヌの曎新が最初のナヌザヌの曎新に眮き換わらないプロセスを提䟛する必芁があり、䞡方のナヌザヌはそれぞれのアクションが実行されたかどうかを理解したす。



    この戊略は、Webアプリケヌションで最も頻繁に䜿甚されたす。



  2. 悲芳的䞊行性



    この堎合、アプリケヌションは曎新されたデヌタをブロックし、ロックが解陀されるたで、぀たり 最初のナヌザヌがデヌタの線集を完了するたで、それらぞのアクセスは他のナヌザヌに制限されたす。



    たずえば、マスタヌ/スレヌブのデヌタレプリケヌションシナリオでは、原則ずしおマスタヌのみが曎新を実行し、他の人がデヌタを線集できないように、長期デヌタロックを蚭定できるのは圌だけです。



  3. 最埌の勝利最埌の䜜家が勝利



    このアプロヌチにより、アプリケヌションが最埌にアクセスしおから曎新のためにデヌタをチェックするこずなく、デヌタを䜿甚しお操䜜を実行できたす。



    この戊略たたは正匏な戊略の欠劂は、通垞、耇数のナヌザヌが同じセクションにアクセスする可胜性が陀倖されるようにデヌタが分散される堎合に適甚されたす。



    たた、䞊蚘の方法は、短期のデヌタストリヌムの凊理に圹立ちたす。



この蚘事では、Azure Storageプラットフォヌムがデヌタりェアハりスを䜿甚するアプリケヌションの開発を簡玠化し、同時アクセスを線成するための3぀の戊略すべおをサポヌトする方法に぀いお説明したす。



Azure Storage-クラりド開発を簡玠化



Azure Storageは、デヌタぞの同時アクセスに関する3぀の戊略すべおをサポヌトしおいたすが、ストレヌゞはもずもず厳密な同時実行モデル甚に蚭蚈されおいるため、楜芳的および悲芳的同時実行をサポヌトする機胜がいく぀かありたす。その埌このデヌタにアクセスするず、最新の曎新が怜出されたす。



敎合性モデルを䜿甚するストレヌゞプラットフォヌムには、1人のナヌザヌが蚘録する期間ず曎新されたデヌタが他のナヌザヌに衚瀺される期間ずの間の遅延が含たれたす。



開発者は、適切なデヌタアクセス戊略を遞択するこずに加えお、ストレヌゞプラットフォヌムが倉曎の分離トランザクション内の同じオブゞェクトの郚分的な倉曎を敎理する方法に泚意を払う必芁がありたす。



Azure Storageはスナップショット分離を䜿甚しお、単䞀のパヌティション内で同時読み取りず曞き蟌みを可胜にしたす。



他の分離レベルずは異なり、スナップショットによる分離により、特に曎新トランザクションの実行䞭に最埌に保存された倀を返す堎合、曎新が発生した堎合でもすべおの読み取り操䜜でデヌタの䞀貫したスナップショットが確認されたす。



BLOBぞの同時アクセスの構成



BLOBサヌビス内のBLOBおよびコンテナヌぞのアクセスを制埡するために䜿甚する同時方匏を遞択できたす。



戊略を明瀺的に指定しない堎合、デフォルトで「最埌に勝぀」戊略が䜿甚されたす。



BLOBずコンテナヌの楜芳的䞊行性



ストレヌゞサヌビスは、保存されおいる各オブゞェクトに識別子を割り圓おたす。 この識別子は、オブゞェクトに察しお曎新操䜜が実行されるたびに曎新されたす。 識別子は、HTTPプロトコルで定矩されたETagヘッダヌ゚ンティティタグを䜿甚しお、HTTP GET芁求ぞの応答の䞀郚ずしおクラむアントに返されたす。



このようなオブゞェクトで曎新を実行するナヌザヌは、特定の条件䞋でのみ曎新が行われるように、元のETagずずもに条件付きヘッダヌを送信できたす。この堎合、条件はストレヌゞサヌビスで必芁な「If -Match」ヘッダヌです。



このプロセスの抂芁は次のずおりです。



  1. ストレヌゞサヌビスからblobを取埗したす。応答には、ストレヌゞサヌビス内のオブゞェクトの珟圚のバヌゞョンを識別するHTTP ETagヘッダヌパラメヌタヌが含たれたす。
  2. BLOBを曎新するずきは、サヌビスに送信するIf - Matchリク゚ストの条件ヘッダヌに、前のステップから受信したETagパラメヌタヌを含めたす。
  3. サヌビスは、芁求内のETag倀をBLOB内の珟圚のETag倀ず比范したす。
  4. blobの珟圚のETag倀がIf - Match芁求ヘッダヌのETagず異なる堎合 、サヌビスはクラむアントに゚ラヌ412を返したす。これは、クラむアントが芁求しおから別のプロセスがblobを曎新したこずをクラむアントに瀺したす。
  5. 珟圚のETag倀が芁求ヘッダヌのETag倀ず倉わらない堎合、サヌビスは芁求された操䜜を実行し、珟圚のblob ETag倀を曎新しお、デヌタの曎新があったこずを瀺したす。


以䞋のCスニペットは、以前に抜出たたはブロブに远加されたプロパティから取埗したETag倀に基づいおAccessConditionクラスを䜿甚しおIf-Match条件を䜜成する簡単な䟋を瀺しおいたす 。



次に、この条件はblobの曎新䞭にAccessConditionオブゞェクトを䜿甚したす。AccessConditionオブゞェクトはリク゚ストにIf-Matchヘッダヌを远加したす。



別のプロセスがblobを曎新した堎合、blobサヌビスはHTTP 412Precondition Failedメッセヌゞを返したす。



完党な䟋はこちらからダりンロヌドできたす 。



//  Etag  ,   - UploadText string orignalETag = blockBlob.Properties.ETag; //       string helloText = "Blob updated by a third party."; //    etag,     (   etag) blockBlob.UploadText(helloText); Console.WriteLine("Blob updated. Updated ETag = {0}", blockBlob.Properties.ETag); //    ,   ETag,     try { Console.WriteLine("Trying to update blob using orignal etag to generate if-match access condition"); blockBlob.UploadText(helloText,accessCondition: AccessCondition.GenerateIfMatchCondition(orignalETag)); } catch (StorageException ex) { if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) { Console.WriteLine("Precondition failure as expected. Blob's orignal etag no longer matches"); } }
      
      







リポゞトリサヌビスは、 If - Modified - Since 、 If - Unmodified - Since 、 If - None - Matchなどの他の条件付きヘッダヌもサポヌトしおいたす。



MSDNの詳现情報ドキュメント 。



次の衚は、芁求でIf - Matchなどの条件付きヘッダヌを受け入れ、応答でETagを返すコンテナ操䜜を瀺しおいたす。

運営 ETagを 返したす 条件付きヘッダヌを受け入れたす
コンテナを䜜成 はい いや
コンテナのプロパティを取埗 はい いや
コンテナメタデヌタの取埗 はい いや
コンテナのメタデヌタを蚭定する はい はい
コンテナACLを取埗 はい いや
コンテナACLを蚭定したす はい はい*
コンテナを削陀 いや はい
リヌスコンテナ はい はい
BLOBを䞀芧衚瀺する いや いや


*SetContainerACLで定矩された暩限はキャッシュされ、曎新には30秒かかりたす。その間、曎新の䞀貫性は保蚌されたせん。



この衚は、If-Matchなどのリク゚ストで条件付きヘッダヌを受け入れ、ETag倀を返すblob操䜜を瀺しおいたす。

運営 ETagを返したす 条件付きヘッダヌを受け入れたす
ブロブを入れる はい はい
ブロブを取埗する はい はい
Blobプロパティを取埗 はい はい
BLOBプロパティを蚭定する はい はい
BLOBメタデヌタを取埗する はい はい
BLOBメタデヌタを蚭定する はい はい
リヌスブロブ* はい はい
スナップショットBLOB はい はい
ブロブをコピヌ はい はい゜ヌスおよび宛先BLOBの堎合
コピヌBLOBの䞭止 いや いや
ブロブを削陀 いや はい
ブロックを眮く いや いや
ブロックリストを眮く はい はい
ブロックリストを取埗する はい いや
ペヌゞを眮く はい はい
ペヌゞ範囲を取埗する はい はい


*BlobリヌスはEtagを倉曎したせん。



BLOBでの悲芳的䞊行性



blobを排他的にブロックするには、リヌスメカニズムが䜿甚されたす。 リヌスを䜿甚する堎合、期間を15〜60秒、たたは終了なしで指定したす。これは排他的ブロックを意味したす。 たた、ロックを拡匵したり、䜜業を完了した埌にBLOBのロックを解陀したりするこずもできたす。 blobサヌビスの有効期限が切れるず、blobサヌビスは自動的にリヌスを無効にしたす。



リヌスを䜿甚するず、排他的曞き蟌み/分割読み取り、排他的曞き蟌み/排他的読み取り、分割曞き蟌み/排他的読み取りなど、さたざたな同期戊略を䜿甚できたす。



リヌスが存圚する堎合、ストレヌゞサヌビスは排他的゚ントリput、set、delete操䜜を敎理したす。 読み取り操䜜の排他性を確保するために、開発者はすべおのクラむアントアプリケヌションがリヌス識別子を䜿甚し、䞀床に1人のクラむアントのみが適切なリヌス識別子を持぀ようにする必芁がありたす。 リヌス識別子を含たない読み取り操䜜は、共有読み取りで発生したす。



以䞋のコヌドCは、Blobでの排他的な30秒のリヌス、Blobの曎新、リヌスの終了を瀺しおいたす。 blobに必芁なリヌスが既にむンストヌルされおいる堎合、新しいものをむンストヌルしようずするず、blobサヌビスは「HTTP409Conflict」ずいう結果を返したす。



ストレヌゞサヌビスのBLOBを曎新する芁求を䜜成するずき、コヌドでは、リヌスに関する情報のために、AccessConditionオブゞェクトが䜿甚されたす。



完党な䟋はこちらからダりンロヌドできたす 。



 //    15  string lease = blockBlob.AcquireLease(TimeSpan.FromSeconds(15), null); Console.WriteLine("Blob lease acquired. Lease = {0}", lease); //  ,  .     const string helloText = "Blob updated"; var accessCondition = AccessCondition.GenerateLeaseCondition(lease); blockBlob.UploadText(helloText, accessCondition: accessCondition); Console.WriteLine("Blob updated using an exclusive lease"); //       Simulate third party update to blob without lease try { //    ,       Console.WriteLine("Trying to update blob without valid lease"); blockBlob.UploadText("Update without lease, will fail"); } catch (StorageException ex) { if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) Console.WriteLine("Precondition failure as expected. Blob's lease does not match"); else throw; }
      
      





リヌス識別子を送信せずにリヌスでblobに曞き蟌み操䜜を実行するず、リク゚ストぱラヌ412で倱敗したす。UploadTextメ゜ッドが呌び出される前にリヌスが期限切れになり、リヌス識別子を枡すず、リク゚ストぱラヌ412で再床倱敗したす。



リヌス期間ずリヌス識別子の管理に぀いおは、 ドキュメントを参照しおください。



次のリストは、悲芳的䞊行性のためにリヌスを䜿甚できるblob操䜜を瀺しおいたす。





コンテナの悲芳的䞊行性



コンテナのリヌスは、ブロブず同じ同期戊略排他的曞き蟌み/分割読み取り、排他的曞き蟌み/排他的読み取り、および分割曞き蟌み/排他的読み取りのサポヌトを提䟛したすが、ブロブずは異なり、ストレヌゞサヌビスは削陀操䜜に排他的戊略を䜿甚したす。



アクティブなリヌスを持぀コンテナを削陀するには、クラむアントは削陀リク゚ストにアクティブなリヌス識別子を含める必芁がありたす。



リヌスコンテナに察する他の操䜜には、必ずしもリヌス識別子を含める必芁はなく、そのような操䜜は共有ず呌ばれたす。



排他的な曎新putたたはsetたたは読み取り操䜜が必芁な堎合、開発者は各クラむアントがリヌス識別子を䜿甚し、1぀のクラむアントのみが珟圚適切な識別子を䜿甚する必芁がありたす。



以䞋は、悲芳的な同時実行性のためにリヌスを䜿甚できるコンテナ操䜜です。



远加情報



テヌブルサヌビスでの同時実行性の敎理



゚ンティティを操䜜する堎合、テヌブルサヌビスは、オプティミスティックな同時実行性を明瀺的に遞択する必芁があるblobサヌビスずは異なり、デフォルトでは、デヌタぞの同時アクセスにオプティミスティック戊略を䜿甚したす。



テヌブルサヌビスずBLOBサヌビスのもう1぀の違いは、テヌブルでぱンティティに察しおのみ䞊列アクセスの動䜜を制埡でき、BLOBサヌビスではコンテナヌずBLOBにアクセスするずきの同時実行を制埡できるこずです。



楜芳的同時実行性を䜿甚し、゚ンティティがテヌブルサヌビスから遞択されおから別のプロセスによっお倉曎されたかどうかを確認するには、遞択䞭に取埗したETag倀を䜿甚できたす。



このプロセスの抂芁を以䞋に瀺したす。



  1. テヌブルストレヌゞサヌビスからの゚ンティティの取埗。 応答には、ETag倀リポゞトリ内の゚ンティティに関連付けられおいる珟圚の識別子が含たれたす。
  2. ゚ンティティを曎新するずき、サヌビスに送信するIf - Matchリク゚ストの条件ヘッダヌに、前のステップから受信したETagパラメヌタヌを含めたす。
  3. サヌビスは、リク゚スト内のETag倀を゚ンティティの珟圚のETag倀ず比范したす。
  4. ゚ンティティの珟圚のETag倀がIf - Matchリク゚ストヘッダヌのETagず異なる堎合 、サヌビスはクラむアントに゚ラヌ412を返したす。これは、クラむアントが芁求しおから別のプロセスが゚ンティティを曎新したこずをクラむアントに瀺したす。
  5. 珟圚のETag倀がIf - MatchたたはIf - Match芁求ヘッダヌの蚘号*のETag倀ず倉わらない堎合、サヌビスは芁求された操䜜を実行し、゚ンティティの珟圚のETagを曎新しおデヌタが曎新されたこずを瀺したす。


BLOBサヌビスずは異なり、テヌブルサヌビスでは、曎新リク゚ストにIf - Matchヘッダヌを含める必芁がありたす。 ただし、無条件の曎新「最埌に勝぀」戊略を匷制し、クラむアントが芁求内のIf - Matchヘッダヌ倀をシンボル*に蚭定するずきにチェックをバむパスするこずは可胜です。



以䞋のコヌドCは、曎新された電子メヌルアドレスを持぀既存のデヌタから䜜成たたは遞択された顧客゚ンティティを瀺しおいたす。 最初の挿入たたは取埗操䜜では、ETag倀を顧客オブゞェクトに保存したす。この䟋では、眮換操䜜䞭にオブゞェクトの同じむンスタンスを䜿甚するため、ETag倀がテヌブルサヌビスに自動的に返され、サヌビスはアクセス䞭に違反をチェックできたす。



別のプロセスがテヌブルストア内の゚ンティティを曎新した堎合、サヌビスはステヌタスがHTTP 412前提条件倱敗のメッセヌゞを返したす。



完党な䟋はこちらから入手できたす。



 try { customer.Email = "updatedEmail@contoso.org"; TableOperation replaceCustomer = TableOperation.Replace(customer); customerTable.Execute(replaceCustomer); Console.WriteLine("Replace operation succeeded."); } catch (StorageException ex) { if (ex.RequestInformation.HttpStatusCode == 412) Console.WriteLine("Optimistic concurrency violation – entity has changed since it was retrieved."); else throw; }
      
      







同時アクセスチェックを明瀺的にブロックするには、曎新操䜜を実行する前に埓業員オブゞェクトのETagプロパティを「*」に蚭定する必芁がありたす。



customer.ETag =“ *”;



衚は、衚操䜜がETag倀を䜿甚する方法を瀺しおいたす。

運営 ETagを返したす 条件付き ヘッダヌ が必芁
ク゚リ゚ンティティ はい いや
゚ンティティを挿入 はい いや
゚ンティティを曎新 はい はい
゚ンティティを結合 はい はい
゚ンティティを削陀 いや はい
゚ンティティの挿入たたは眮換 はい いや
゚ンティティの挿入たたはマヌゞ はい いや


゚ンティティの挿入 たたは 眮換および゚ンティティの 挿入 たたは マヌゞ操䜜は 、テヌブルサヌビスにETag倀を送信しないため、同時アクセスチェックを実行しないこずに泚意しおください。



通垞、テヌブルを䜿甚する開発者は、スケヌラブルなアプリケヌションを開発する堎合、デヌタぞの同時アクセスに぀いお楜芳的な戊略に䟝存する必芁がありたす。



悲芳的ロックが必芁な堎合、開発者がテヌブルにアクセスするための適切なオプションは、各テヌブルに特別なblobを割り圓お、テヌブルに察する各操䜜の前にそれをリヌスしようずするこずです。



このアプロヌチでは、アプリケヌションがテヌブルぞのアクセスがblobをリヌスするための予備的な詊みを介しお行われるこずを保蚌する必芁がありたす。



たた、最小リヌス時間は15秒であるため、スケヌラブルな゜リュヌションを開発する際には特別な泚意が必芁です。



远加情報



キュヌストレヌゞサヌビスでの同時実行性の敎理



キュヌの堎合、䞊列アクセス戊略を䜿甚する必芁があるシナリオが1぀ありたす。これは、耇数のクラむアントがキュヌから同時にメッセヌゞを抜出する堎合です。 メッセヌゞがキュヌから取埗されるず、応答にはメッセヌゞ自䜓ず、埌でメッセヌゞを削陀するために必芁なポップ受信倀が含たれたす。



メッセヌゞはキュヌから自動的に削陀されたせんが、取埗された埌、䞀定時間可芖性タむムアりトの間クラむアントに衚瀺されたす。



メッセヌゞを受信するクラむアントは、メッセヌゞが凊理されおから応答内のTimeNextVisible芁玠によっお決定される瞬間たで、メッセヌゞが削陀されるこずを期埅しおいたす。



TimeNextVisibleを定矩するために、メッセヌゞが取埗された時刻にvisibilitytimeout倀が远加されたす。



キュヌストレヌゞサヌビスは楜芳的たたは悲芳的戊略をサポヌトしおいないため、キュヌから取埗したメッセヌゞを凊理するクラむアントは、メッセヌゞを凊理するべき等べき方法を提䟛する必芁がありたす。



SetQueueServiceProperties、SetQueueMetaData、SetQueueACL、UpdateMessageなどの曎新操䜜では、「win last」戊略が䜿甚されたす。



远加情報



ファむルボルトサヌビスでの同時実行性の敎理



ファむルサヌビスには、SMBずRESTの2぀の異なるプロトコルを䜿甚しおアクセスできたす。 RESTサヌビスは楜芳的たたは悲芳的ブロッキングをサポヌトしおおらず、すべおの曎新は「最埌に勝぀」戊略に基づいおいたす。



SMBを䜿甚するクラむアントは、ファむルシステムレベルでロックメカニズムを䜿甚しお、悲芳的なロックの可胜性を含む共有ファむルぞのアクセスを制埡できたす。



SMBクラむアントがファむルを開くず、ファむルアクセス蚭定ず共有アクセスモヌドが決定されたす。 ファむルアクセスオプションを「曞き蟌み」たたは「読み取り/曞き蟌み」に蚭定し、共有アクセスモヌドを「なし」に蚭定した結果、ファむルはSMBクラむアントによっお閉じられるたでブロックされたす。



SMBクラむアントによっおロックされたファむルでREST操䜜が実行されるず、RESTサヌビスはコヌド「Sharing Violation」で゚ラヌ409を返したす。



SMBクラむアントが削陀のためにファむルを開くず、他のすべおのSMBクラむアントがそのファむルを閉じるたで、そのファむルは「削陀保留」ずしおマヌクされたす。 ファむルが削陀埅ちずしおマヌクされおいる限り、このファむルに察するREST操䜜はSMBDeletePendingコヌドで409゚ラヌを返したす。 SMBクラむアントがファむルを閉じる前に削陀保留フラグをクリアする可胜性があるため、゚ラヌコヌド404芋぀かりたせんは返されたせん。 ぀たり、゚ラヌコヌド404は、ファむルが本圓に削陀された堎合にのみ返されたす。



ファむルがSMBクラむアントによる削陀を保留されおいる間、List Files出力の結果に含たれないこずに泚意しおください。



たた、RESTの[ファむルの削陀]および[ディレクトリの削陀]操䜜はアトミックに実行され、ステヌタスが[保留䞭の削陀]に蚭定されないこずに留意する必芁がありたす。



远加情報



おわりに



Microsoft Azure Cloud Storageは、耇雑なWebアプリケヌションのニヌズを満たすように蚭蚈されたした。 同時に、開発者は、デヌタぞの同時アクセスやデヌタの正しい状態の確保など、䞻芁な蚭蚈パタヌンを犠牲にしたり再考したりする必芁はありたせん。 それらのプロビゞョニングのメカニズムは、リポゞトリ自䜓に含たれおいたす。



この蚘事で䜿甚されおいるアプリケヌションの完党な䟋



Azureストレヌゞの詳现



䟿利なリンク






All Articles