1. 雨宿りとWEBの小噺.fm
  2. Season -No.229 朝活「Redis E..
2023-05-11 23:48

Season -No.229 朝活「Redis Explained」をダラダラ読む回

はい.第229回は


Redis Explained

https://architecturenotes.co/redis/


を半分だけ読みました💁

自分も使ったことがありますが,今はこれだけ進化していたことに驚きました!まさに本番DBとして使えるなと思います.それをどういう設計になっているのか?というお話もされており,とてもおもしろかったので,ぜひ皆さんも読んでみてくださいー


ではでは(=゚ω゚)ノ


  • Redis
  • memcached
  • in memory
  • database
  • Architectures
  • High availability (HA)

See Privacy Policy at https://art19.com/privacy and California Privacy Notice at https://art19.com/privacy#do-not-sell-my-info.

00:03
はい、5月4日、木曜日ですね。 遅刻は昨日13分になりました。ゴールデンウィークもガンガン入って、連休2日目ですかね、僕としては。
ちょっと寝不足でごめんなさい。めっちゃ朝早く、遅くなってしまいました。ごめんなさいね。 はい、おはようございます。miminokeethの桑原です。では、本日も朝活を始めていきたいと思います。
今日読む記事ですけどもね、今日もなんかいろんな記事を見つけて、読みたいものがいっぱいあるんですけど、 やっぱりソースコードとか画像がたくさん出てきて、
あまり朝活向けというか、音声配信向けじゃない記事がいっぱいあるんですね。 技術的な記事なので仕方ないんですけど、しっかりその辺も読んでいきたいし、技術のキャッチアップはしていきたいんですけど、
朝活用として、これ今日どうかなっていうのはあったんですけど、レディスエクスプレイン、その名前の通りですね、レディスっていうのをたった1枚の記事としてまとめられた記事があって、それを今日読んでいこうと思います。
画像もたくさんあるんですけど、どちらかというと設計だったり、そういう思想とか手法みたいなところが結構テキストベースで書かれているので、おそらく音読でもいけるんじゃないかと思っております。
ところで、では早速入っていきたいと思います。
ゆ、勉強中さんですね。はい、おはようございます。ご参加いただきありがとうございます。今日もいつも通りダラダラと読んでいこうと思っております。
じゃあ早速入っていきましょう。レディスエクスプレインですね。レディスに関するあらゆることを技術的に深く掘り下げていきますと。
レディスの様々なトポロジ、データの永続性、プロセスの分岐というのをカバーしますと。
これが前提でした。本記事ですけど、一番最初にこの記事の概要というか全容を一枚の画像でペッて貼られてますので、それ見てもらっても全然いいと思うんですよね。
なるほどこういうことを語るのねっていう話だと思いますけど。
はい、またちょうどこの記事のリンクもツイッターでシェアするので、皆さんの方でも読んでいただければと思います。
はい、思います。じゃあ続いていきましょう。What is Redis? レディスとはそもそも何ぞやというお話からですね。
レディスとはですね、リモートディクショナリーサービスの略で、これはオープンソースのいわゆるキーバリューのデータベースサーバーになりますね。
いわゆるノーエスケールのものですけど、レディスの最も正確な説明はデータ構造サーバーであるということになりますと。
このレディス特有の性質が開発者の間で多くの人気と採用につながっています。
業を繰り返して相当し順序づけるのではなく、データが最初から欲しいデータ構造になっていたらどうでしょうかと。
初期にはMemcachedと同じように使われていたんですけど、レディスが改良されるにつれて、
Publish、サブスクライブ機能とか、ストリーミング、Queueなど他の多くのユースケースで実行可能にもなりましたと。
これがレディスが人気な理由ですよね。
単なるストリング文字列型もあれば、そのビットマップのものもあれば、ビットフィールドもあれば、ハッシュですね。
いわゆるオブジェクトのキーバリューというハッシュも行けますし、いわゆるリストも行けますし、セットですよね。
Javascriptのセットも行けたりしますし、あらゆる形のデータフォーマットをストレージで管理できるという感じですね。
03:02
これが本当に強いなと思いました。
僕も使ったのはだいぶ前ですけど、そこからさらに進化しているっぽいので、改めて使ってみたいというのは何だかんだありますね。
技術の興味・関心という意味では。
レディスは主にMySQLやPostgreSQLのような本物のデータベースの前に、
キャッシュとして使用されるいわゆるインメモリデータベースで、アプリケーションのパフォーマンスを向上させるのにも役立ちます。
メモリーの速度を活用し、中央のアプリケーションデータベースの負荷を軽減します。
変更頻度が低く、頻繁に要求されるデータ、もしくはミッションクリティカルではなくて、頻繁に進化していくデータ。
上記のデータの例として、セッションやデータのキャッシュ、もしくはダッシュボード用のリーダーボードとか、ロールアップ分析などがあります。
これらのデータというのは、わざわざ本当のデータベースですね。
RDSとかにアクセスするのではなくて、その前段に置いておいて、早くユーザーにデータを返してあげるというところですね。
とにかく早く、高速にデータを返してユーザーにアプリケーションを使わせてあげたいというところの需要に対して、Redisを挟んであげるという感じですね。
あとキャッシュも効くので、そこも本当に大きいと思いますね。
では続いていきましょう。しかしですね、多くのユースケースにおいて、Redisというのは本格的なプライマリーデータベースとして使用できる十分な保証というものを実は提供しています。
というので、インメモリデータベースなんですけど、実際本格的なガチのデータベースとして使うことも全然今はいけるよって話ですね。
Redisプラグインとか様々な高可用性ですね、というのの設定と相まって、データベースとしてのRedisというのは特定のシナリオやワークロードで非常に有用なものになっております。
もう一つの重要な点は、Redisがキャッシュとデータストアの境界線をあいまいにしたことです。
これが良い悪いで結構議論分かれる気がしますけど、僕は難しいですね。一概に答えは言いづらいなというか、良い面悪い面両方あれだと思ったので。
ここで理解すべき重要な点というのは、メモリー上のデータを読み込んで操作することは、いわゆるSSDやHDDを使った従来のデータストアでは不可能なほど高速であるということですね。
そっちも十分速いっちゃ速いんですけど、それ以上に速くなったよというところですね。
ちなみにそれがどれくらい速くなったかというところなんですけど、それがまた画像で貼られてますので、それも見てみてもらえればと思います。
ちょっと口頭で説明しても伝わりづらいと思うんで、これ本当に百分は一見にしかないので見てみてください。
かなりRedisは速いですよねということですね。
続きましていきましょう。
もともとRedisというものは当時不揮発性の永続性を持たないMemcachedと比較されることはほとんどでした。
そうですね。Memcachedと比較されることは本当に多いと思いますし、僕も昔は全然比較してました。
逆に言うとそれくらい揮発性が高かったというのがやっぱりデカいですよね。
という意味でMemcachedも結局揮発性が高いので同じようなものですよね。
そしてどっち使うかみたいな話だったんですけど、ちょっとMemcachedの説明が入ってますね。
06:00
Memcachedというのは2003年にブラッドなんちゃらさんによって作られて、Redisよりも6年早くこのように登場しました。
当初はPerlのプロジェクトとしてスタートし、後にC言語で書き直されたもので、当時のデファクトキャッシュツールでした。
最初Perlだったんですね。
多分Perl5でしょうね、おそらく。
Redisとの主な違いというのはデータの型がないこと。
LRU、Least Recent Useというだけという限定的な対比ポリシーです。
本当にキャッシュですね、名前の通りキャッシュに特化したデータベースだったんですね。
もう一つの違いはRedisがシングルスレッドであるに対しMemcachedはマルチスレッドであると。
あ、そうなんや。
Memcachedは厳密なキャッシュ環境では高性能かもしれませんが、分散クラスターでは多少の設定が必要であるのに対しRedisは最初からそのサポートもありますと。
だから両方とも一長一短あるってわけですね。
なるほどでした。
でもなんかシングルスレッドなんですねRedisの方が。
だからこそJSで使いやすいってのがあるかもしれないですけど。
なるほどね。
Redisは結構使ったんですけどMemcachedはほぼほぼ使ってなかったんで、
自面で見てなるほどねっていう感じでしかないですけどね。
はい、で、戻ります。
この2つのキャッシュの能力の内訳は現在の以下の通りですというところで、
テーブルが貼られてますのでちょっと音読で申し訳ないんですけど一応見ていきたいと思いますけど、
まず、サブミリセカンドレイテンシーですね。
レイテンシーとしてはRedisもMemcachedも両方ともイエスで備えてますよと。
デベロッパーイーズオブユースですね。
開発者向けですかってところで両方ともイエスですと。
あとデータパーティショニングか。
データのパーティショニングができますかってところでそれも両方ともイエスですね。
まあそれはキーバリュー型だからそうだよねって感じですけど。
サポートフォーブロードセットオブプログラミングランゲージズってところですね。
こちらも両方ともイエスですと。
続いてアドバンストデータストラクチャーってところなんですけど、
アドバンスってどれぐらいアドバンスかはちょっとわからないですけど、
少なくともいろんなデータの構造を対応しているというか、
データ構造を取り込めるって話でいくとRedisはイエスなんですけど、
Memcachedはないよって話でした。
続いてマルチスレッディットアーキテクチャですね。
逆に言うとMemcachedはデータ構造に対してはあまりできないけど、
マルチスレッドのアーキテクチャっていうところにはMemcachedはイエスなんですね。
Redisはできないよって話です。
あとはスナップショット、レプリケーション、トランザクション、パブリックもしくはサブですね。
あとはルアースクリプティングとかジオスパシャルサポート、
ロケーションじゃなくてジオスパシャルっていう話だった。
今言った合計6つですね。
これら6つに関してはMemcachedは全部ノーですね。
Redisだけイエスだと。
スナップショットもやっぱあるのは結構Redisでかいようなと思いますね。
こういうところがあるので本当に本番用としてのデータベースで使えるとこが大きいかもしれない。
あとはレプリケーション、トランザクション。
トランザクションもやっぱあるっていうのはやっぱデータベースに触ると絶対トランザクション欲しくなるので、
そういう意味でいくとRedisはトランザクションもあるって意味だと本当に本番データベースとして使ってよさそうっていうのは確かにそうかもねっていうのはありますね。
09:01
はい戻ります。
現在ではそのディスクへのデータの永続化方法っていうのを設定することができますが、
Redisが導入された当初はスナップショットを使用してメモリ上のデータの非同期コピーをディスクに永続化し長期保存していました。
結局無理やりコピーをとって、なんとか同期をとって永続化っていうのをやってたってことですね。
ははー。まあまあまあ。
残念ながらこの秘孔にはスナップショット間でデータが失われる可能性があるという欠点もあります。
そりゃそうだよ。
Redisは2009年に誕生して以来色々成熟してきました。
Redisをデータストレージのシステムの武器に加えることができるように、そのアーキテクチャとトポロジーの大部分をカバーしております。
この2つのフローによってRedisは長期保存が可能になり、様々なレプリケーション戦略をサポートし、
より複雑なトポロジーを可能にしました。
Redisがデータを永続化するように設定されていない場合、再起動やフェイルオーバーの際にデータが失われます。
そりゃそうだよね。
再起動時に永続化を有効にすると、RDBスナップショットまたはAOFの全てのデータをメモリロードし直し、
インスタンスが新しいクライアントリクエストをサポートできるのももちろんなります。
ということで、より分散したRedisのセットアップについてちょっと見てみましょう。
続いてRedis HAですね。
レプリケーションの話ですね。
厳密に言うとHAはHigh Availabilityですね。
高可用性ってやつですけど。
続いてHAの話です。
Redisのもう1つの一般的なセットアップっていうのは、
メインデプロイメントとレプリケーションで同期されたセカンダリーデプロイメントの組み合わせになります。
メインインスタンスにデータが書き込まれると、
セカンダリーインスタンス用のレプリカクライアント出力バッファーにコマンドのコピーが送信され、
レプリケーションが促進されます。
セカンダリーインスタンスはデプロイメントの内部の1つまたは複数のインスタンスに設定することができます。
これらのインスタンスはRedisからの読み込みを拡張したり、
メインが失われた場合にフェールオーバーを提供したりするのにも役立ちます。
文字通りセカンダリーということですね。
一応ここで高可用性についての法則もあるので、そこも一応読んでおきましょう。
HA、High Availability、いわゆる高可用性とは、合意されたレベルの運用精度、通常はアップタイムを平均よりも高い期間に確保することを目的としたシステムの特性です。
このようなHAシステムでは単一障害点を作らないことが重要であり、システムは優雅かつ迅速に回復することもできます。
その結果プライマリーからセカンダリーへの移行時にデータが失われることなく、
また障害を自動的に検知して復旧することができる信頼性の高いクロスオーバーを実現しています。
レプリケーションですけど、RedisのメインインスタンスにはレプリケーションIDとオフセットというのがあります。
この2つのデータはレプリカがレプリケーションプロセスを計測できる時点、または完全な同期を行う必要があるかどうかを判断するために重要なものです。
このオフセットはメインのRedisデプロイメントで発生するアクションごとにインクリメントされます。
インクリメントってことは単純に数字で管理してるんですね。
より具体的には、Redisレプリカインスタンスがメインインスタンスから数オフセットだけ遅れてる時に、
プライマリーから残りのコマンドを受け取り、同期が取れるまでそのデータセットで再生をします。
12:00
若干のラグというか、サブが出てしまうってことか。
2つのインスタンスがレプリケーションIDで合意できない場合、またオフセットがメインインスタンスに不明な場合、
不明な場合ってあるんだ。へー。
レプリカは次に完全同期を要求します。
これにはプライマリーインスタンスが新しいRDBスナップショットを作成し、
それをレプリカに転送することが図ります。そりゃそうでしょうね。
この転送が行われている間、メインインスタンスはスナップショットのカットオフと現在のオフセットの間の
全ての中間更新をバッファリングし、スナップショットと同期した後にセカンダリに送信します。
完了するとレプリケーションは通常通り継続できます。
こんなことを内部でやってくれてるけど、僕らはそれを知らないで、
ただコマンドを送ればいいという設計になっているというので、本当にありがたいですね。
ただ、この処理をするときだけ時間のラグはありますけど、
これいわゆるCDN的な層ですよね。このレディスっていうのは。いわゆるメモリーキャッシュなので。
この層でこんな風にレプリケーションまでやってくれるっていうのはやはり強いですね。
当分レディスはまだまだ使われ続けるんだろうなっていう感…
幸運を読む限り感触はありますね。
はい、すいません。戻ります。
インスタンスが同じレプリケーションIDとオフセットを持つ場合、それらは正確に同じデータを持っています。
さて、なぜレプリケーションIDが必要なのか不思議に思われるかもしれません。
レディスインスタンスがプライマリーに昇格したり、プライマリーとしてゼロから再起動したりすると、
新しいレプリケーションIDが付与されますと。
なるほど、レディスインスタンスがプライマリーに昇格とかあるんだ。
つまり複数のインスタンスが発生させているけど、どれかが落ちたりした時にメインとして昇格は果たすというのはあり得るってことですね。
逆にそれぐらいできるような柔軟性もちゃんと確保してあるってことですね。
これは新しく昇格したセカンダリーがレプリケーションしていた以前のプライマリーインスタンスを推測するために使用されます。
そのためのIDなんですね。
これによって新しいプライマリーインスタンスが古いレプリケーションIDを覚えているため、
他のセカンダリーと部分的な同期を実行することもできます。
突合させたりとか同期するときのためのどれですかっていうのを指定するためのIDですね。
例えばプライマリーとセカンダリーの2つのインスタンスでレプリケーションIDは同じだがオフセットが数百コマンド違う場合、
オフセットがすぐ後ろにあるインスタンスでそれらを再生すると同じデータセットになります。
レプリケーションIDが全く異なる場合は、また新たに降格、もしくは再酸化したセカンダリーの以前のレプリケーションIDですね。
共通の祖先がいない場合になっちゃいますねこれは。
その場合はわからなくなってしまいます。
高価なフルシンクを実行する必要がありますというので、
はいはい、もう全部フルに舐めてもう一回シンクしなきゃいけないというところですね。
レプリケーションIDがなくなる可能性は多いでありますね。
ここがやっぱり揮発性の宿命と言いますか、再起動したときに消えるというところの課題。
課題じゃないけど、ある意味でそれを受け入れているからこその高速化ってのがやっぱりありますよね。
あるいは以前のレプリケーションIDを認識していれば、
両者が共有する共通の祖先を推論することもできるので、
15:03
データを同期させる方法を推論することができ、
オフセットは部分同期に再び意味を持つようになりますということでした。
はい、でも結構レリスの、僕レプリケーション実は使ったことがないんですよね。
それぐらい古いときかな。
多分それがリリースされていないときに使ったのか、僕から知らなかっただけかわかんないですけど。
ここまでしっかりでも設計されているというので、確かに本当にデータベース使えそうですね。
困ったら一旦レリスに頼ってみて、本当にサービスとかアプリケーションというところがスケールする場合に
ちゃんとRDBに移るというのも一つありかもしれないですね。
では続いて、次のセクションはレリスセンチネルですね。
センチネルというのは分散型システムのことです。
すべての分散システムと同様に、センチネルにはいくつかの利点ともちろん欠点はあります。
センチネルというのは、レリスの効果要請を提供するために、状態を調整するために一緒に働く
センチネルプロセスのクラスターというのが存在するように設計されています。
結局のところ、障害からあなたを守るシステムがそれ自身の単一障害点を持つことは望まないでしょうと。
そりゃそうだよね。本末転倒というか、ミイラ取りがミイラみたいな感じですね。
センチネルはいくつかのことを担当します。
まず、現在のメインとセカンダリのインスタンスが機能し応答しているということを確認します。
いわゆるヘルスチェックに近い役割をするということですね。
これはセンチネルが失われた状況に対して警告し行動することができるために必要です。
第二に、他のシステムにおけるズーキーパーやコンサルのようなサービス発見の役割も果たします。
つまり、新しいクライアントがレリスに何かを書き込もうとするとき、
センチネルは現在のメインインスタンスが何であるかをクライアントに伝えます。
さっきのヘルスチェックもそうだけど、バランシングじゃないけどその辺ですね。
前段に何か立っていろんなことを確認してくれる役割をしてくれるんですね。
窓口に近いところかな。
つまりセンチネルは常に可用性を監視し、その情報をクライアントに送信することで、
本当にフェイルオーバーが発生した場合に対応できるようにしています。
その責務ということですね。今言った責務をちょっと列挙していきます。
合計4つありますよと言ってますね。改めて今言った責務をまとめているだけですけど。
1つ目モニタリングです。メイン及びセカンダリインスタンスが期待通りに動作していることをまず確認するというモニタリング。
続いて通知です。ノーティフィケーションですけど、
レリスインスタンスで発生したことをシステム管理者に通知します。
続いてフェイルオーバー管理ですね。
センチネルノードっていうのがあって、そのノードはプライマリインスタンスが利用できない、
もしくは十分な数のノード、クオラムが同意した場合にフェイルオーバープロセスを開始することができます。
ラスト4つ目ですね。構成管理ですけど、
センチネルノードっていうのは現在のメインレリスインスタンスを発見するポイントとしても機能しています。
ちょっと4つ目が、名前と説明があんまりピンとこなかったな。
このようにレリスセンチネルを利用することで、障害検出が可能になってきます。
18:01
この検出には現在のメインインスタンスが利用できなくなったことに同意する複数のセンチネルプロセスが含まれます。
この合意プロセスはクオラムと呼ばれます。
これにより堅牢性が向上し、1台のマシンが誤動作してメインのレリスノードに到達できなくなることも防いでいます。
本当にだからクラスターなんですね。
今ちょっと出てきたクオラムってやつですけど、一応これについても解説があるので読んでおきますけど、
クオラムとは分散システムがフェイルオーバーなどの操作を行うために必要な最小限の投票数のことです。
この数は設定可能なんですけど、分散システムのノード数を反映したものにする必要があります。
それはそうだよね、なんか文脈的に。
ほとんどの分散システムでは3または5のサイズでそれぞれ2または3のクオラムが設定されています。
ノードのサイズとクオラムのサイズは実は一致しないということですね。
ちょっと少ないぐらいでちょうどいいことか。
奇数ノードはシステムが同数を解除する必要がある場合に推奨されます。
レディスクラスターの直前で切りますね、ごめんなさい。
はい、じゃあ続けていきましょう。
このセットアップにデメリットがないわけではないので、
レディスセンチネルを使用する際の推奨受講やベストプラクティスをいくつか紹介することにします。
もうベストプラクティスもあるんですね。
レディスセンチネルというのはいくつかの方法で導入できます。
正直なところ、まともな提案するには、あなたのシステムに関して私が現在持っている以上のコンテキストが必要です。
一般的なガイダンスとして、私は可能であれば、
各アプリケーションサーバーの脇にセンチネルノードを実行することをお勧めします。
そりゃそうだよな。
これによってセンチネルノードと実際にレディスを使用しているクライアント間の
ネットワーク到達性の違いというのを考慮する必要はありません。
それは勝手にやってくれるからですね。
センチネルをレディスインスタンスと並行して、
あるいは独立したノードで実行することもできますが、
その場合様々な意味で物事が複雑になります。
そりゃそうだよね。
私は少なくとも3つのノードと少なくとも2つのクオラムを実行することをお勧めします。
最小限ですね、これ。
以下はクラフター内のサーバーの数とそれに関連するクオラム、
および持続可能な許容故障を分類した簡単なチャートになります。
ここもチャートがテーブルになっていますね。
縦のカラムにサーバーの数とクオラムの数と
number of tolerated failuresですね。
失敗許容数のところ。
この3つが分かれていて、横軸はそれの単純に数字が述べられています。
サーバー1個に対してクオラムはもちろん1個で、
さっきのfailuresとが0です。
サーバー2の時もクオラムは2ですね。
サーバー3の時も2で良いと。
サーバー4つの時はクオラム3に増やすのが良さそうじゃないのって話です。
その時はfailure1は出ると。
サーバー5、6、7といくんですけど、
基本的には数字が偶数になるときにだいたい上がっているのかな、これは。
なのでサーバー6の時にクオラムは4になります。
7の時も4ですね。
多分この増え方でいくと、サーバーが8までいくとクオラムは5に増えるんでしょうね。
そんな感じだと思いますけど。
21:00
だから半分プラス1くらいかな、最大値かなっていうことですね。
で、その時のfailureの数は半分マイナス1くらいまでは許容できるってことですね。
マイマントレディスのベーストプラクティスにはそんな感じの設定だそうですね。
で、サーバーとクオラムの数と許容される故障数の表ですけど、
これはシステムによって異なりますが、
基本一般的な考えがこれになっていると。
このようなセットアップで何が問題になるのか少し考えてみましょう。
このシステムを長く運用すればそのすべてのことにぶつかることになりますと。
はい。
で、だいたい3つくらい語られてますけど、
センチネル濃度がクオラムから外れたらどうしますかっていうのが1つ目。
ネットワークが分裂して古いメインインスタンスが少数派になったらどうしますかと。
これらの書き込みはもちろんどうなるかと。
ネタバレとしたシステムが完全に回復した時点で失われちゃうよっていう答えを言ってますね。
3つ目にセンチネル濃度とクライアント濃度、
いわゆるアプリケーション濃度のネットワークトポロジーがずれていった場合はどうなるでしょうかみたいなお話です。
この3つがよくある問題なんですね。
特にディスクへの映像化、公述しますけど、
映像化っていうのが非同期であるため、耐久性の保証はありません。
またクライアントが新しいプライマリを知った時に、
プライマリを知らないためにどれだけの書き込みが失われたかみたいな厄介な問題もあります。
Redis は新しい接続が確立された時に新しいプライマリを問い合わせることを推奨しています。
システム構成によってはこれは重大なデータ損失というのも意味します。
メインインスタンスが最低1つのセカンダリインスタンスに書き込みをレプリケートするように強制すれば、
損失のレベルを軽減する方法がいくつかあります。
Redis のレプリケーションは全て非同期であり、トレードオフであることを忘れないでください。
そのため独立に確認応答を追跡する必要もあり、
少なくとも1つのセカンダリインスタンスによって確認されない場合はメインインスタンスは書き込みを受け入れるのを停止しますよ。
そんな設定になっています。
というところで、今のが Redis のフォーラムとセンチネの話でした。
今日の時間は30分くらい来たので、ここで区切って、明日は Redis クラスターの話で続きを読んでいきたいと思います。
すみません、途中中途半端だったらいつも通りグダグダしたので申し訳ないですけど、ご了承いただければ幸いです。
じゃあまた明日もこれから続きを読んでいきたいと思いますので、興味ある人は参加してみてください。
後ほどこの記事自体もツイートしますので、ご自身でも1回読んでいただくといいと思いますし、
画像を見ていただくと、なるほどって多分わかりやすいと思うので、これを見ていただくといいと思います。
本日の参加者はエプテラノードさんとケンジさんとYouUnderbar勉強中さんですね。
ご参加いただきありがとうございました。
またゴールデンウィーク中ですね。
旅行に出かける方もいらっしゃるでしょうし、しっかり開発もしくは勉強に注力する方もいらっしゃるでしょうけど、
ゆっくりリフレッシュしていただければなと思います。
それでは終了したいと思います。
お疲れ様でした。
23:48

コメント

スクロール