Mercurial > hg > Papers > 2022 > ikki-master
view slide/thesis.pdf.html @ 28:7174f22ed695
tweak
author | ichikitakahiro <e165713@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 10 Feb 2022 23:55:41 +0900 |
parents | 3f39907150c5 |
children | bca6c79006cf |
line wrap: on
line source
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>GearsOSの分散ファイルシステムの設計</title> <meta name="generator" content="Slide Show (S9) v4.1.0 on Ruby 2.6.8 (2021-07-07) [universal.x86_64-darwin21]"> <meta name="author" content="Takahiro Ikki, Shinji Kono" > <!-- style sheet links --> <link rel="stylesheet" href="s6/themes/screen.css" media="screen"> <link rel="stylesheet" href="s6/themes/print.css" media="print"> <link rel="stylesheet" href="s6/themes/blank.css" media="screen,projection"> <!-- JS --> <script src="s6/js/jquery-1.11.3.min.js"></script> <script src="s6/js/jquery.slideshow.js"></script> <script src="s6/js/jquery.slideshow.counter.js"></script> <script src="s6/js/jquery.slideshow.controls.js"></script> <script src="s6/js/jquery.slideshow.footer.js"></script> <script src="s6/js/jquery.slideshow.autoplay.js"></script> <!-- prettify --> <link rel="stylesheet" href="scripts/prettify.css"> <script src="scripts/prettify.js"></script> <style> .slide {page-break-after: always;} </style> </head> <body> <div class="layout"> <div id="header"></div> <div id="footer"> <div align="right"> <img src="s6/images/logo.svg" width="200px"> </div> </div> </div> <div class="presentation"> <div class='slide cover'> <table width="90%" height="90%" border="0" align="center"> <tr> <td> <div align="center"> <h1><font color="#808db5">GearsOSの分散ファイルシステムの設計</font></h1> </div> </td> </tr> <tr> <td> <div align="left"> Takahiro Ikki, Shinji Kono 琉球大学理工学研究科情報工学専攻 <hr style="color:#ffcc00;background-color:#ffcc00;text-align:left;border:none;width:100%;height:0.2em;"> </div> </td> </tr> </table> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsosのファイルシステムの設計と実装">GearsOSのファイルシステムの設計と実装</h2> <ul> <li>DataGearとCodeGearという単位を用いるOS</li> <li>従来のファイルシステムには型とTransactionが無い</li> <li>DataGear単位のTransactionとしてファイルシステムを設計</li> <li>APIとしてTake/Put/Peekを採用した</li> <li>通信としてもDBアクセスとしても使える(メモリからSSDへの通信に見える)</li> <li>本研究ではsocket baseな通信とWordCountの例題を作成した</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsosの基本単位">GearsOSの基本単位</h2> <ul> <li>CodeGear <ul> <li>実行Codeの単位</li> <li>入力DataGearと出力DataGearを持つ</li> <li>goto文(jump命令)を使って遷移する</li> <li>実行単位は途中で割り込まれたりしない(Atmocity)</li> </ul> </li> <li>DataGear <ul> <li>Cの構造体に相当する</li> <li>ノーマルレベルでは変更されない(関数型プログラミング)</li> </ul> </li> <li>C言語を拡張する形でCbC言語により実装される(gcc/llvm)</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="codegearとdatagear">CodeGearとDataGear</h2> <ul> <li>InputDataGearを受け取って、CodeGearが処理し、OutputDataGearを出力する</li> <li>OutputDataGearは次のCodeGearのInputDataGearとなる</li> <li>ファイルシステムではDataGearをkeyで待ち合わせる</li> </ul> <div style="text-align: center;"> <img src="images/cg-dg.pdf" alt="cgdgの関係図" width="600" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsosのinterface">GearsOSのInterface</h2> <ul> <li>JavaのInterfaceに相当する</li> <li>APIとなるCodeGearの名前と型を書く(__next(…)が継続)</li> <li>引数渡しの構造体として使う(引数はすべてここに定義される必要がある) <pre><code>typedef struct Tree<>{ union Data* tree; struct Node* node; __code put(Impl* tree,Type* node, __code next(...)); __code get(Impl* tree, Type* node, __code next(...)); __code remove(Impl* tree,Type* node, __code next(...)); __code next(...); } Tree; </code></pre> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="interfaceの呼び出し">Interfaceの呼び出し</h2> <ul> <li>createで作成する(通常の関数呼び出し)</li> <li>DataGearとして作成する場合はnewを使う</li> <li>gotoでputAPIを呼び出す(nextは継続)</li> <li>InterfaceなどのDataGearはプロセスに相当するContextにすべて格納される <pre><code>struct Queue* queue = createSychronizedQueue(context); struct Task* task = new Task(); goto queue->put(task, next(...)); </code></pre> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="interfaceの実装">Interfaceの実装</h2> <ul> <li>Interfaceの実装に使われるデータ構造を記述するImplementがある</li> <li>実装で使われるDataGearを記述する(ヒープに確保される)</li> <li>create時にAPIを実装するCodeGearをInterfaceの構造体に代入される <pre><code>typedef struct SynchronizedQueue <> impl Queue { struct Element* top; struct Element* last; struct Atomic* atomic; } SynchronizedQueue; </code></pre> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="codegearとdatagearにはメタレベルなものが存在する">CodeGearとDataGearにはメタレベルなものが存在する</h2> <ul> <li>メタレベルな記述はトランスコンパイラにより自動生成される(記述することも可能)</li> <li>CodeGearの前後にMetaなCodeGearが挿入される</li> </ul> <div style="text-align: center;"> <img src="images/meta-cg-dg.pdf" alt="ノーマルレベルとメタレベルの視点からのGearの関係" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="stubcodegearとgoto-meta">stubCodeGearとgoto meta</h2> <ul> <li>ContextからInputDataGearを取り出す(stubCodeGear)</li> <li>OutputDataGearをContextに書き込み、次のCodeGearを呼び出す(goto meta)</li> <li>stubCodeGear/goto metaは変更可能(メタプログラミング)</li> </ul> <div style="text-align: center;"> <img src="images/meta-cg-dg.pdf" alt="ノーマルレベルとメタレベルの視点からのGearの関係" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsosのファイルシステムの設計">GearsOSのファイルシステムの設計</h2> <ul> <li>DataGearの単位でデータを操作したい</li> <li>通信データに対応した複数のストリームを持つ</li> <li>Transactionとしてatomicに操作したい <ul> <li>従来のファイルシステムはTransactionはUserレベルで実装される</li> </ul> </li> <li>ファイル操作と通信を同じAPIで実現する <ul> <li>ChristieのDataGearManagerを参考にする</li> <li>Take/Put/Peek</li> </ul> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="takeputpeek">Take/Put/Peek</h2> <ul> <li>ファイルはQueueで構成される</li> <li>putでQueueに追加</li> <li>takeでQueueからの取り出し</li> <li>peekでQueueから取り出さない読み出し</li> </ul> <div style="text-align: center;"> <img src="images/QueueElement.pdf" alt="Queueの構造" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsfsのトランザクション">GearsFSのトランザクション</h2> <ul> <li>GearsOSのCodeGear操作はatomicなので割り込まれない <ul> <li>atomicityはOSが保証する</li> <li>これによりTake/Put/PeekがTransactionであることを保証する</li> </ul> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="queueによるgearsosのファイル">QueueによるGearsOSのファイル</h2> <ul> <li>GearsOSのファイルはDataGearを保持するQueueとなる</li> <li>オンメモリのファイルに相当する</li> <li>Queueをデバイスにcopyして持続性を実現する</li> <li>書き込み先はDataGearManagerで選択する</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="putのimplementation">PutのImplementation</h2> <ul> <li>QueueのElementをnewで作成する</li> <li>Queueのリンクを構築する</li> <li>継続nextに跳ぶ <pre><code>__code putSingleLinkedQueue(struct SingleLinkedQueue* queue, union Data* data, __code next(...)) { Element* element = new Element(); element->data = data; element->next = NULL; queue->last->next = element; queue->last = element; goto next(...); } </code></pre> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="takeのimplementation">TakeのImplementation</h2> <ul> <li>QueueからElement経由でDataGearを取り出す</li> <li>Queueのリンクを修正し、nextでデータを引き渡す</li> <li>Elementには任意の型のDataGearが格納されている <pre><code>__code takeSingleLinkedQueue(struct SingleLinkedQueue* queue, __code next(union Data* data, ...)) { printf("take\n"); struct Element* top = queue->top; struct Element* nextElement = top->next; if (queue->top == queue->last) { data = NULL; } else { queue->top = nextElement; data = nextElement->data; } goto next(data, ...); } </code></pre> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="datagearmanager">DataGearManager</h2> <ul> <li>Take/Put/PeekはDataGearManagerに対して行う</li> <li>メモリ上のQueueはLocalDGMになる</li> <li>RemoteDGMは他のノードやプロセスあるいはストレージデバイスをあらわす</li> <li>一つのDataGearManager上に複数のQueueがあり、keyで識別する</li> <li>RemoteDGMに書き込むと相手のLocalDGMに書き込まれる</li> <li>Take/Peekは書き込みを待ち合わせる</li> <li>複数のTakeを待ち合わせることができる</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="datagearmanagerによる通信構成">DataGearManagerによる通信構成</h2> <ul> <li>任意の相手のRemoteDGMを作成することでTopologyが形成される</li> <li>手元のRemoteDGMに書き込むと相手のLocalDGMに書き込まれる</li> <li>RemoteDGMはproxyとして動作する</li> <li>この構成は分散フレームワークChristie(当研究室作成)と同じ</li> </ul> <div style="text-align: center;"> <img src="images/Remote_DataGearManager.pdf" alt="RemoteDGMの関係図" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="socket通信によるremotedgmの実装">socket通信によるRemoteDGMの実装</h2> <ul> <li>GearsOSはUnix上の言語フレームワークとして実装されている</li> <li>Unixのsocket通信を使ってQueueのputを実装する</li> <li>proxy側はQueueにputされたDataをsocketで送信する</li> <li>送信されたDataはLocal側でgetDataAPIで取り出される</li> <li>send/recvはUnixのAPI <pre><code>__code sendDataRemoteDGMQueue(struct RemoteDGMQueue* cQueue, union Data* data, __code next(...), __code whenError(...)){ char recv_buf; int send_size, recv_size; send_size = send(cQueue->socket, data, sizeof(union Data), 0); recv_size = recv(cQueue->socket, &recv_buf, 1, 0); //error処理は省略 goto next(...); } </code></pre> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="受信側の実装">受信側の実装</h2> <ul> <li>ファイル本体(Local側)はsocketからDataを取り出す</li> <li>取り出されたデータはQueueにputされる <pre><code>__code getDataLocalDGMQueue(struct LocalDGMQueue* cQueue, __code next(...), __code whenError(...)){ int recv_size, send_size; char send_buf; union Data* recv_data; recv_size = recv(cQueue->socket, recv_data, sizeof(union Data), 0); //error処理は省略 Gearef(context, cQueue)->data = recv_data; goto putLocalDGMQueue(recv_data, next); } </code></pre> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="複数のストリームから構成されるファイル">複数のストリームから構成されるファイル</h2> <ul> <li>入力されるデータに応じた個別のstreamを備えたい <ul> <li>例えばUSBは複数のチャネルを持つ</li> <li>メタデータの取り出しは別streamになる</li> <li>通信として使う場合に複数のプロトコルがある方が良い(FTP)</li> </ul> </li> <li>Streamはkey nameを持ち、keyでアクセスを行う</li> <li>赤黒木を用いる</li> <li>DataのTake/Put時には必ずkey nameの指定が必要となる</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="socketを使ったremotedgm">socketを使ったRemoteDGM</h2> <ul> <li>RemoteDGMに書き込みが行われるとsocketで通信が起きる</li> <li>受信側はLocalDGMにDataGearを書き込む</li> </ul> <div style="text-align: center;"> <img src="images/socketCom.pdf" alt="socketを通じたレコード送信" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="wordcountの例題">wordCountの例題</h2> <ul> <li>ファイル内の文字列を1行づつ受け取り、文字列,行数をカウントする例題</li> <li>文字列送信側とCount側を別ノード上で行うことで、ファイルの呼び出しと通信処理が構成できる</li> <li>RemoteDGMへの書き込みで通信する</li> <li>acknowredgeを逆方向のRemoteDGMによる通信で実現する(現在は直接送信)</li> </ul> <div style="text-align: center;"> <img src="images/slideGearsWC.pdf" alt="リモートDGMによるWordCount" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsfile-apiによるwordcount13">GearsFile APIによるWordCount(1/3)</h2> <ul> <li>FileOpen側(NodeA)とWordCount側(NodeB)でノードが別れる</li> <li>(手順1)FileOpen側はFilePloxyにDataRecordをputする</li> <li>(手順2)WordCount側は処理の後、ackを返信する</li> </ul> <div style="text-align: center;"> <img src="images/slideGearsWC.pdf" alt="ChristieAPIによるWordCount" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsfile-apiによるwordcount23">GearsFile APIによるWordCount(2/3)</h2> <ul> <li>(手順3)1,2をループし、FileOpen側はEoFならフラグを送信する</li> </ul> <div style="text-align: center;"> <img src="images/slideGearsWC.pdf" alt="ChristieAPIによるWordCount" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsfile-apiによるwordcount33">GearsFile APIによるWordCount(3/3)</h2> <ul> <li>(手順4)EoFを受信したWordCountは結果を返信し、双方の処理を終了させる</li> </ul> <div style="text-align: center;"> <img src="images/slideGearsWC.pdf" alt="ChristieAPIによるWordCount" width="800" /> </div> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="現在のgearsfile-apiの開発状況">現在のGearsFile APIの開発状況</h2> <ul> <li>実装ずみ <ul> <li>keyアクセスに対応したファイル通信 <ul> <li>単一のQueueによる通信の記述</li> </ul> </li> <li>リストとなるTree <ul> <li>赤黒木</li> </ul> </li> <li>atomicな操作が行えるQueue <ul> <li>複数からのアクセス時にデータ整合を保つ</li> </ul> </li> </ul> </li> <li>実装中 <ul> <li>keyアクセスが行えるQueueのリスト</li> <li>リスト単位での通信の記述</li> </ul> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="結論">結論</h2> <ul> <li>GearsOSのファイルの設計を行った <ul> <li>ファイルの構造の設計 <ul> <li>DataGear単位での操作が行える</li> </ul> </li> <li>socketによる通信部分の実装 <ul> <li>GearsOS上でのソケット通信の記述</li> </ul> </li> <li>APIの段階的な設計記述 <ul> <li>Proxyによるファイル通信</li> </ul> </li> <li>GearsOSの調査</li> </ul> </li> <li>Streamのリスト単位での通信の完成</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="将来的な課題">将来的な課題</h2> <ul> <li>TopoplogyManagerの設計 <ul> <li>参加したノードを任意の形のTopologyに接続する機能</li> <li>ファイルシステム向けの機能を追加したい <ul> <li>DNS</li> <li>中枢としてのTopologyのノード監視</li> </ul> </li> </ul> </li> <li>Securityシステムの追加 <ul> <li>証明書などによるファイル操作制限</li> <li>不正な分散ファイルシステムへのアクセス</li> </ul> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="gearsosの生成形の問題点">GearsOSの生成形の問題点</h2> <ul> <li>GearsOSのメタレベルの処理の記述はトランスコンパイラにより行われる</li> <li>場合によりメタレベルの記述を行わなくてはならない <ul> <li>他のInterfaceを継承したオブジェクトからのDataGear継承 <ul> <li>例)Queueからのデータ取り出し</li> <li>トランスコンパイラはどのInterfaceに記述されたDataGearを参照するべきか判断が難しい</li> </ul> </li> </ul> </li> </ul> <pre><code>__code Task2(TQueue* localDGMQueue){ goto localDGMQueue->take(Task3); } __code Task3(TQueue* localDGMQueue, FileString* string){ printf("take[%s] [num:%d]\n", string->str, string->size); goto getData(); } //プログラマが実装したいstub __code Task3_stub(struct Context* context){ TQueue* localDGMQueue = (struct TQueue*)Gearef(context, TQueue)->tQueue; FileString* string = Gearef(context, TQueue)->data; goto Task3(context, localDGMQueue, string); } //自動生成されたErrorなstub __code Task3_stub(struct Context* context) { TQueue* localDGMQueue = Gearef(context, TQueue); FileString* string = Gearef(context, FileString); goto Task3(context, localDGMQueue, string); } </code></pre> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="並列処理構文par-gotoが持つ問題">並列処理構文par gotoが持つ問題</h2> <ul> <li>par gotoとはGearsOSに実装された並列処理構文である</li> <li>StreamQueueに対するput/takeの並列処理の実装をpar goto構文で試みた</li> <li>par gotoはトランスコンパイラへの依存性が高い <ul> <li>stubCodeGearのように任意な書き換えが行えない</li> </ul> </li> <li>特定のCodeGearの宣言のみでしか正常な処理が生成されない <ul> <li>Interfaceに記述されたAPICodeGearではバグが生じる</li> <li>par gotoでの使用を前提としたCodeGearを書かなくてはならない</li> </ul> </li> <li>処理が重いという問題点も存在する</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="以下返答用">以下返答用</h2> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="takeputpeek-1">Take/Put/Peek</h2> <ul> <li>PeekはReadOnly (最新の設定を読みこむなど)</li> <li>Take/PutはDGが一つならUpDataに相当する</li> <li>書き込みが単一スレッドなら順序は保証される</li> <li>書き込みが複数の場合、Putの順序は保証されない</li> <li>データベースとの違い <ul> <li>putがQueueとして蓄積される</li> <li>Keyが一つしかない(通信路として使える)</li> </ul> </li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="__code-nextint-ret-の意味">__code next(int ret, …)の意味</h2> <ul> <li>軽量継続を表す</li> <li>nextは引数として渡されたCodeGear</li> <li>int ret は返す値</li> <li>…は軽量継続の呼び出された時の値渡しのInterface</li> <li>一段の呼び出しStackのような役割になる</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="codegearと再帰呼び出し">CodeGearと再帰呼び出し</h2> <ul> <li>再起呼び出ししなければ関数呼び出し的に使える(末尾再起)</li> <li>再帰呼び出ししたい場合、明示的に自分でStackを作る</li> <li>…はContextにすべて置かれている</li> <li>Processはすべて異なるContextを持っている</li> <li>Context自体は共有されない</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="datagearの型">DataGearの型</h2> <ul> <li>union Data は一つのプロセス(Context)で使われるすべてのDataGearのUnion</li> <li>メタ部分に型に対応する番号を持っている</li> <li>番号を使って型を識別することができる</li> <li>任意の型を格納できるQueueやStackを作成することが可能</li> <li>メタレベルではunion Dataを使ってDataGearの詳細に立ち入らず処理できる</li> </ul> </div> <div class='slide'> <!-- _S9SLIDE_ --> <h2 id="remotedgmとacknowledge">RemoteDGMとacknowledge</h2> <ul> <li>Take/Put/Peekのコマンドは TCP上でacknowledgeを使って通信されている</li> <li>これとは別に自分と相手のCodeGearどうしのacknowledgeが必要</li> <li>RemoteDataGearManager経由でacknowledgeを返すのが正しい</li> <li>しかし、acknowledgeが重複してしまう</li> <li>メタプログラミングを利用してこの重複を消すことは可能 <ul> <li>しかし煩雑</li> </ul> </li> </ul> </div> </div><!-- presentation --> </body> </html>