カテゴリーアーカイブ インフラ

takahashi 著者:takahashi

dockerのコンテナ名(container_name)はかぶると共存できない

dockerで使用されるコンテナ(docker上での個々の仮想マシンのこと)にはランダムなIDが割り付けられますが、これとは別に、ユーザーが任意の名前を付けることができます。

そのためわかりやすい名前をつけておけばそれを使用してコンテナの操作を行うことができるためとても楽です。

一方で、このユーザーが指定できるコンテナ名は重複することができず、ほかに同名のコンテナ名が存在すると重複した時点でエラーとなってしまいます。

docker-compose up -d
...省略...
Creating mysql              ... error
ERROR: for mysql  Cannot create container for service mysql: b'Conflict. The container name "/mysql" is already in use by container "コンテナID". You have to remove (or rename) that container to be able to reuse that name.'
...省略...
ERROR: for mysql  Cannot create container for service mysql: b'Conflict. The container name "/mysql" is already in use by container "コンテナID". You have to remove (or rename) that container to be able to reuse that name.'
ERROR: Encountered errors while bringing up the project.
Failed to deploy 'Compose: docker-compose.yml': `docker-compose` process finished with exit code 1

このエラーによく遭遇するシチュエーションとしては、docker-composeを使用した一括構築を行った際、複数のComposeファイルを使用して同じDockerホスト上で構築を行うと、各Composeファイルに記述されているコンテナ名が一般的なもの(例えばMySQLが入っているコンテナには”mysql”という名前がついていたりなど)になっていることがあるため、しばしばエラーとなってしまいます。

この場合は、Composeファイル(docker-compose.yml)内の

“container_name”

ディレクティブを既存のコンテナと被らないように変更すれば、共存させることが可能です。

例えば、複数のdocker-compose.yml内での指定で

...省略...
  mysql:
    container_name: "mysql"
...省略...

のように指定がかぶってしまっている場合は

...省略...
  mysql:
    container_name: "mysql_service1"
...省略...

のように名前を変えておくことで、共存させることが可能になります。

dockerはOSからアプリケーションまでの間の部分の構築もかなり簡単にしてくれるので、複数人で同じ環境を再現して開発を行いたい場合はとてもありがたい仕組みではあるのですが、一部環境に合わせて設定を変更しなければならない場合もあるので、この辺りは注意が必要になりそうですね。

  • この記事いいね! (0)
takahashi 著者:takahashi

なぜネットの調子が悪いと”169.254″から始まるIPアドレスになるのか

家やオフィスなどでルータやネットワーク機器がおかしくなっていたりすると、よく”169.254…”から始まるアドレスが割り振られることがあります。

なぜこんな変なアドレスが割り振られるのか、疑問に思った方も多いと思います。

WindowsやmasOSをはじめとしたOSでは、DHCPなどのIPアドレスの割り当てをしてくれる仕組みがLAN内になく、かつ機器に対して固定のIP設定も行われていない場合に、同じLAN内に接続された機器と協調しながら自動で独自のIPアドレスを割り振る機能(APIPA)が備わっています。

この機能によって割り当てられるIPアドレスを“自己割り当てIPアドレス”もしくは”リンクローカルアドレス“と呼びます。

自己割り当てIPアドレスの仕組みはいたって単純です。

同じLAN内にある全機器に対して、

“169.254.XXX.XXXっていうIPを使おうと思うんだけど、ほかにだれか使ってる人いる~?”

って聞いて、”俺使ってるぞー”っていう応答が返ってこなければ自分のIPとして使用する、という仕組みになっています。

ちなみに、なぜ169.254.XXX.XXXの範囲のIPアドレスが振られるかというと、ローカルIPと同様に、169.254.0.0~169.254.255.255(169.254.0.0/16)までのアドレスが、この自己割り当てIP用として正式に予約されているからです。

リンクローカルアドレス – Wikipedia

これでDHCPがなくても、インターネットに抜けることができない代わりに、特に何も指定しなくても同じLAN内で自己割り当てIPで参加する機器同士であれば通信することができるようになります。

自己割り当てIPについてはこちらのサイトが詳しかったので、上記の説明で分からなかった…という方は確認してみてください。

リンクローカルアドレス – Geolocation Technology

要するに、自宅やオフィスのLANなどで、IPの自動割り当てのしくみ(DHCP)が存在するにも関わらず自己割り当てIPが振られてしまった場合は、何らかの原因でPCがDHCPサーバーとの通信に失敗したということになります。

この場合はPCとDHCPを担当する機器(家の場合はほとんどルーターが行っている)との接続ができているか、ルーター自体の動作は正常か…といったあたりを調べるとたいていの場合は解決の近道になります。

もし169.254…から始まるアドレスが割り振られてしまった場合は、上記の部分を確認してみてください。

  • この記事いいね! (0)
takahashi 著者:takahashi

Cookieを規制する法案が浮上 Webサービスへの今後の影響が心配…

先日、気になるニュースを見かけました。

CookieはステートレスであるWebの仕組み上ユーザーを識別する数少ない手段となっています。

例えば、会員制サイトでアクセスしてきたユーザーがログイン済みなのか、まったく関係のない(会員ではない)部外者なのか、の判別にはCookieの存在が不可欠です。

Cookieがなければ、ログインを前提とした会員制サイトを作ることは事実上難しくなるでしょう。

正確にはCookieのURLにセッションIDを乗せることで、Cookieを使用しない状態の管理行うことはできますが、URLはCookieよりも漏れやすい情報(ユーザーがURLを意図的に保存しなくても、ブラウザの履歴に残ったり、リファラーという仕組みで分かってしまったりする)ため、URLを盗まれてしまうと第三者が正規のユーザーに成り代わって会員サイトを操作できてしまう”セッションハイジャック”が発生しやすくなってしまいます。

ただし、クッキーレス・セッションにはセキュリティ上の問題がある。というのも、クッキーレス・セッションを利用した場合、(当たり前の話であるが)セッションIDが一般ユーザーの目に直接さらされることになる。つまり、URLさえ分かってしまえば、第三者による「なりすまし」も可能であるということだ。
 ただし、このクッキーレス・セッションの脆弱性の問題は、クッキー経由でセッションIDの受け渡しを行った場合でもさほど事情は変わらない。ネットワークをモニタすることで、クッキーの内容などは簡単に盗聴できてしまうからだ。ただ、URLの方が「なりすまし」も「盗聴」も簡単であるという意味で、より危険であるといえる。しょせんは相対的なものといってしまえばそれまでだが、安全性がより重視される局面で、無用にクッキーレス・セッションを採用するべきではない

[ASP.NET]クッキーをサポートしないクライアントでセッション機能を利用するには? – @IT

もちろんURLによるクッキーレス・セッションもシステムによっては適用できる場合もありますが、セキュリティに気を使いたいサイトの場合は当然 Cookieという選択肢が存在しなければなりません。

Cookieという選択肢が取れなくなってしまった場合は、非常に大きな問題です。

そのような技術的な裏側を知ってか知らずかわかりませんが、昨今”個人情報保護”という観点だけを重視してしまい、Cookieを規制しようとする政治的な動きが出てきていますが、正直言って理解に苦しみます。

もっとも、現在多くのサイトで行われている”Cookieを使用することに同意を求める”だけであれば(めんどくさいですが)画面を追加するだけなので問題ありません。

しかし、Cookieの使い方そのものを規制するような動きが万が一出てきた場合、ITインフラそのものを崩壊に追い込んでしまうことも考えられます。

現状”Cookieを規制するようだ”という動きだけニュースになっていて、具体的にどのような規制が行われるのかを説明しているところはまだないようですが、いくらITに詳しくないとはいえ、”知らないから”という言い逃れは許されない問題です。

関係者の方には是非Webの技術やCookieをなぜ使用するのかをきちんと勉強していただいた上で議論していただきたいと思います。

  • この記事いいね! (0)
takahashi 著者:takahashi

docomoがついにFOMA(3G)の終了を発表!? 電波の届きやすさへの影響が心配…

先日、NTT docomoがFOMAの終了を発表しました。

 「FOMA」および「iモード」のサービス終了について <2019年10月29日> – NTT docomo

FOMAとは、docomoでの3Gサービスの名前で、今回の発表はつまりdocomoの3G対応携帯電話(およびスマートフォン)のサービスが使えなくなることを意味します。

FOMAのサービスが終了した時点で、3G通信までにしか対応していない従来のガラケーはすべて使用不能となるわけですが、個人的に気にしているのは4G以上に対応したスマートフォンの”フォールバック機能”としての3G利用も終了するのかどうかについてです。

現行の4Gとまもなく登場予定である次世代の通信規格の5Gは、3Gと比較して電波が届く範囲が狭い性質があり、現状でも4G以上の電波がつかめない場合は3Gにフォールバックすることで接続を維持する仕組みがどのスマートフォンにも入っています。

田舎や山間部などではこの機能のおかげで何とか携帯電話が利用できていた、という地域もまだまだあるかと思うのですが、もし3Gの電波そのものが停波されるとなると、こういった地域では携帯電話が利用できなくなる可能性があり、事実上のサービスエリアの縮小を招く恐れが出てきます。

特に緊急時に携帯電話が必要になる場面を考えると、4G以上の電波が届きにくい、人の少ない場所の場合が多いと思う(人も多く、設備も整っている場所では最悪携帯が使えなくても助けを呼ぶ手段がある)ので、そういった場所で今後携帯電話が使用不能になるのではないかと不安です。

また、4G対応のスマートフォンであっても、VoLTEに対応していない機種を使っている場合は音声通話のみ3G回線を利用しているため、3Gが停波した場合はこういった機種で音声通話が利用不能となります。

“4Gをつかんでいるから”と思っていたらある日音声通話が使えなくなって混乱が発生する、といった状況にならないかも不安なポイントです。

auはすでに停波を予告していますし、docomoが停波するとなれば必然的にSoftbank/Y!Mobileも追従せざるを得なくなると思いますので、おそらく全社で3G廃止の流れが来ることは間違いないかと思います。

フォールバックも含めた3G停波は行われるのか。3G停波までの間に上記のような問題に各キャリアがどこまで対応してくれるのか。

今後注意深くチェックしていく必要がありそうです。

  • この記事いいね! (0)
takahashi 著者:takahashi

UNIX系OSのsudoコマンドにsudoersファイルの制限を無視してroot権限でコマンドが実行できる脆弱性が発覚

最近のUNIX系のOSにおいて、直接rootユーザーとしてログインする代わりに、1コマンド単位でroot権限に昇格できるコマンドとしてsudoが用意されています。

現在では、rootユーザーとしてログインするよりも一般ユーザーでsudoを使用した方が安全といわれていますが、そんなsudoに先日、ちょっとマズい脆弱性が発覚しました。

Linuxの「sudo」コマンドにroot権限奪取の脆弱性。ユーザーID処理のバグで制限無効化 – engadget 日本版

sudoには特定のコマンドのみroot権限で実行可能とするような、各ユーザーに対するコマンド単位での制限を設定することができます。

例えば、設定ファイルやサービスの起動・停止はできるようにしたいが、サーバー自体の再起動・停止はさせないようにしたい…などどいった場合は、対象のユーザーに対してのみshutdownコマンドなどをroot権限で実行することを制限することができます。

ところが今回、sudoコマンドでrootユーザーではなく特定のユーザーとして実行すると、sudoersで指定された制限を無視して、すべてのコマンドをroot権限として実行できてしまう現象が発見されました。

sudo で UID に「-1」または「4294967295」を指定すると root 権限でコマンド実行出来る脆弱性 – らくがきちょう

詳細は上記のリンクを参照いただきたいのですが、一部のコマンドのみsudo経由で実行できるように許可されたユーザーにおいて、ユーザーidが”-1″、もしくは” 4294967295″のユーザーを指定した場合にsudo のバグで制限なくroot権限が発動できてしまう、というのが今回判明した現象です。

なお、もともとsudoを使用する権限が一切ないユーザーについては上記のユーザーidのユーザーとして実行しようとしてもはじかれる為、管理者でない一般ユーザーが管理者権限を行使できてしまう、といったことはないようです。

自分でも更新前のsudoで試してみましたが、昇格はできませんでした。

 sudo -u#-1 service nginx reload
[sudo] password for testuser: 
testuser is not in the sudoers file.  This incident will be reported.

基本的にsudoは完全な管理者として昇格する以外の使い方はあまりされていない印象なので、おそらく影響を受けたユーザーはさほど多くないかと思いますが、もしコマンド単位での制限をかけている場合は、早急にsudoのアップデートを適用すべきでしょう。

  • この記事いいね! (0)
takahashi 著者:takahashi

さくらのクラウド GSLBで常に1つのIPアドレスだけ返すようにする方法

さくらのクラウドで利用できるロードバランサの一つに、GSLBというものがあります。

これはトラフィックを裏側のインスタンスなどに再分配するのではなく、インターネットと直接接続された(グローバルIPを持っている)複数のインスタンスに割り当てられたIPを返却してクライアントにランダムなインスタンスへアクセスさせるIPアドレスベースのロードバランサです。

さくらのクラウド上では通常のトラフィック分配を行うロードバランサと比較して安価で、仕組みもシンプルでわかりやすく、そしてリージョンにまたがって運用することができる点はメリットです。

さてこのさくらのクラウドのGSLBですが、デフォルトの設定のままで複数インスタンスを登録すると、

;; ANSWER SECTION:
lbtest.example.com. 29 IN CNAME  site-XXXXXXXXXXXX.gslb3.sakura.ne.jp.
site-XXXXXXXXXXXX.gslb3.sakura.ne.jp. 9 IN A    1台目のサーバーIP
site-XXXXXXXXXXXX.gslb3.sakura.ne.jp. 9 IN A    2台目のサーバーIP

さくらのクラウドのDNSサーバーからは上記のように、登録したインスタンスの全IPアドレスが 一度に 返されてしまいます。

この場合、どのインスタンスへつなげに行くのかの挙動がクライアント側任せになってしまい、クライアント側の実装によってはどちらかの特定の インスタンス につなげ続ける”偏り”が発生してしまう可能性があります。

負荷をなるべく均等に分配したい場合は、これでは困ってしまいます。

このGSLB機能には、実は詳細設定があり、各インスタンスのIPの出力比率を偏らせることができます。

通常、重みをつけて運用してしまうと、IPの出力が非均等になってしまいますが、すべてのインスタンスの重みの値を同一にしておけば、均等の確率でいずれかのインスタンスのIPが出力されます。

GSLBの設定画面の右上のメニューから”監視・応答方法の変更”をクリックします。

すると下記のような画面が出てきます。

赤枠で囲った”重み付け応答を”有効”に変更します。

この状態でもう一度DNSの設定値を確認してみると

;; ANSWER SECTION:
lbtest.example.com. 21 IN CNAME  site-XXXXXXXXXXXX.gslb3.sakura.ne.jp.
site-XXXXXXXXXXXX.gslb3.sakura.ne.jp. 1 IN A    サーバー1のIP
;; ANSWER SECTION:
lbtest.example.com. 29 IN CNAME  site-XXXXXXXXXXXX.gslb3.sakura.ne.jp.
site-XXXXXXXXXXXX.gslb3.sakura.ne.jp. 1 IN A    サーバー2のIP

このようにインスタンスのいずれか1つのIPのみ応答されるようになります。

これなら余分なIPアドレスが同時に配信されることがないので、より均等にアクセスを振り分けることができそうです。

なお、一部のChrone系などのWebブラウザでは、DNSサーバーで設定されているTTL(キャッシュの有効期限)よりも長くDNSの値を保持しようとするようなので、注意が必要です。

  • この記事いいね! (0)
takahashi 著者:takahashi

さくらのクラウドで停止させたくないインスタンスを停止時に自動で再起動させる方法

さくらのクラウド上の仮想サーバーにおいて、何かの拍子にシャットダウンしてしまったり、といったトラブルは、実稼働中のサーバーインスタンスでは避けたいものです。

ただ、何か問題が発生してシャットダウンしてしまった場合、止まってしまったOS自身からはもちろん制御することができないため、外部から何らかの操作を行わない限りは自動で復旧できません。

さくらのクラウドには”タグ”という、各リソースにタグ付けをしてグループ分けをする機能があります。

実はこのタグ機能に、@から始まる特定のタグを入れておくと、単に分類だけではなく、特定の動作をさせることができるような仕組みがあります。

例えば、今回のようにサーバーを停止させたくない場合は

@auto-reboot

というタグを追加しておくと、ダッシュボードから操作を行わない限りインスタンスが電源off状態になっても自動的に再起動されます。

ちょっと隠し機能感満載の仕組みですが、別で監視用のインスタンスやサービスなどを利用することなく再起動してくれるのはありがたいですね。

自動再起動以外にもいくつかオプションがあるようですので、さくらのクラウドでサーバーを動かしている方はぜひ確認してみてください。

特殊タグ一覧 – さくらのクラウド ドキュメント

  • この記事いいね! (0)
takahashi 著者:takahashi

Certbotで証明書の更新後に自動で特定の処理をさせる方法

無料でSSL証明書を発行してもらえるサービスであるLet’s Encryptですが、同時に更新とSSL証明書の設定の自動化を行うCertbotという仕組みを提供しているのも特徴です。

このCertbotですが、いくつかプラグインがあり、ワイルドカード(任意のサブドメインに適用できる)SSL証明書を取得しない場合、メインで使用しているWebサーバー向けのCertbotプラグインを使用すると、自分の方で細工しなくても、Webサーバーを停止することなく自動で取得時の認証や証明書の適用を行ってくれます。

ただ、ワイルドカード証明書の場合はDNS-01という、ドメインを登録しているDNSサーバーを使用した認証方法に限定されてしまうため、上記のようなWebサーバー向けのプラグインを使用することができません。

この場合、ワイルドカード証明書を取得時、もしくは更新時にSSL証明書のインストールや差し替えは行われますが、Webサーバーへの自動適用は行われません。

この状態のままだと、せっかくSSL証明書を自動で更新できても、自動でWebサーバーに読み込まれないため、”いつの間にか期限切れになってた…”なんて状況が発生してしまうことになります。

そこで、僕の場合はSSL更新時に合わせてWebサーバーを自動的に再起動できるように、スクリプトを次のようにしていました。

/usr/bin/certbot renew --force-renew >> /var/log/letsencrypt/ssl-renew.log 2>&1 && service webサーバーのサービス名 restart >> /var/log/letsencrypt/ssl-renew.log 2>&1

ただこの方法では、まれにSSL更新とWebサーバーの再起動のタイミングが悪く、Webサーバーの再起動が失敗してしまうことがありました。

SSL更新からWebサーバー再起動の間で数秒間マージンを置くことで一応はちゃんと動作するようになったのですが、あくまで固定した秒数待つだけで、SSLの更新状態のチェックなどは行っていないため、必ずしも対策できているとはいいがたい状況でした。

さてどうやればうまくできるかなーと考えていたところ、実はCertbot自体に、処理完了後に特定のコマンドを実行させることができる機能があることを知りました。

例えば、証明書取得時のコマンドに

sudo certbot certonly --manual \
-d example.com -d *.example.com -d ...  \
-m mail@example.com \
--agree-tos \
--manual-public-ip-logging-ok \
--preferred-challenges dns-01 \
--server https://acme-v02.api.letsencrypt.org/directory

のようにするかと思いますが、このコマンドに

--post-hook="実行したいコマンド"

のようなオプションを付加することで、SSL取得処理終了後に指定したコマンドを実行してくれます。

例えば、証明書取得終了後にnginxを再起動させたい場合は

sudo certbot certonly --manual \
-d example.com -d *.example.com -d ...  \
-m mail@example.com \
--agree-tos \
--manual-public-ip-logging-ok \
--preferred-challenges dns-01 \
--server https://acme-v02.api.letsencrypt.org/directory
--post-hook="service nginx restart"

のようにすると、SSL取得処理が終了した時点でnginxを再起動させることができます。

取得時に指定したオプションはcertbotの設定ファイルに記録されるため、2回目以降の更新時では

sudo certbot renew

とするだけでpost-hookも含めて処理してくれるようになります。

なお、このpost-hookはssl証明書の処理が完了したら、失敗・成功にかかわらず実行する、という指定になってますが、処理前に実行させたり、証明書更新が行われた後のみ実行、といった指定も可能となっているようです。

Let’s EncryptのSSL証明書更新時にサービスを再起動する – Qiita

このあたりの設定をうまく使えば、運用がより楽になりそうですね。

  • この記事いいね! (0)
takahashi 著者:takahashi

CentOS 7 のApache 2.4でmpmを切り替える方法

Apacheには、mpmと呼ばれる動作モードがあります。

最近のApacheでは、デフォルトで”prefork”が指定されているかと思います。

このモードでは、1アクセスごとに1つのApacheプロセスを立ち上げ、ブラウザからサイトへの要求にこたえます。

この方式では、アクセスが増えれば増えるほどApacheのプロセスが増えていくため、大量のアクセスが来るとOSの負荷が増えてしまい、サーバー全体の動作が重くなってしまいます。

一方、MPM動作モードには workerとeventとよばれるものもあります。

これらのモードを使用すると、使用されるプロセス数を節約することができるため、サーバー全体への負荷を少なくすることができます。

ただし、ノンスレッドセーフなモジュールを使用している場合などはそのモジュールは使用できなくなるとのことで、注意が必要です。

さて、このMPMの切り替えですが、OSによっては設定ファイルが分散化されていることがあります。

CentOS 7 の場合は

/etc/httpd/conf.modules.d/00-mpm.conf

にMPMの切り替えが行える記述があるので、ここを変更します。

# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so


内容としては非常に親切で、コメントアウトの付け替え後、Apacheを再起動するだけでMPMの切り替えを行うことができます。

上記の例では、6行目のmpm_prefork(Preforkモード)が有効になっています。

例えば、もしworkerモードを有効にしたい場合は、12行目の

#LoadModule mpm_worker_module modules/mod_mpm_worker.so

の先頭のコメントアウト(#)を外し、先程の6行目の

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

の先頭に#をつければOKです。

# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so


この状態で

sudo apachectl configtest #設定が間違っていないかチェック
sudo systemctl restart httpd #Apache再起動

とすればMPMを切り替えることができます。

・変更前

$ sudo apachectl -V
...
Server version: Apache/2.4.6 (CentOS)
Server built:   Aug  8 2019 11:41:18
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture:   64-bit
Server MPM:     prefork
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)
...

・変更後

$ sudo apachectl -V
...
Server version: Apache/2.4.6 (CentOS)
Server built:   Aug  8 2019 11:41:18
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture:   64-bit
Server MPM:     worker
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)
...

Server MPMの部分が切り替わっていることが確認できるかと思います。

素のApacheの場合は元の設定ファイルであるhttpd.confに統合されていたりするので、あらかじめわかりやすく別ファイルに準備されているのはありがたいですね。

  • この記事いいね! (0)
takahashi 著者:takahashi

Redisの用途

最近ふと興味がわいて、NoSQLのことを調べてたりします。

NoSQL(Not only SQL)とはMySQLやPostgreSQLのような従来のRDBとは異なるデータの持ち方の概念(データモデル)でデータを管理するデータベースシステムのことです。

なぜわざわざRDBとは違うシステムが必要になるのかというと、RDBだけではうまく対応できないような場面や、RDBでない方が都合がよいケースが存在するためです。

例えば、有名なMastodonはNoSQLの一つであるRedisをプロセス間のデータ共有に使用していますが、これをもしRDBで置き換えたなら、おそらくリアルタイムに次々とデータが投稿されるMastodonでは追い付かなくなるでしょう。

Redisならインメモリにデータが保持されているので、このあたりの処理がRDBと比較して高速化できます。(ただし、NoSQLにはデータの整合性や、RDBのような複雑な条件での検索などが弱いため、この部分は逆にRDBで補うことになります。)

そんなRedisですが、具体的にどんな場合で利用すると効果的なのか、ちょっと調べてみました。

・複雑なデータを保持するキャッシュストレージとして使う

例えばWebsocketを使ったシステムをNode.jsとApache+PHPの組み合わせで構築した場合、Node.jsとApache(PHP)は別の環境で動作しているため、そのままではデータの共有ができません。

そこで、同じデータを参照できるようにするために、データの橋渡し役が必要になります。

RDBやファイルといった選択肢もありますが、ここにRedisを使うことで、高速かつある程度複雑な構造のデータも簡単に扱うことができるようです。

・キャッシュしたデータを(半)永久的に保持したい

RedisはMemcachedとよく比較されますが、Memcachedは再起動すれば値が消失してしまうのに対し、RedisはファイルとしてDBのデータを保持しておく仕組みもあるため、設定をしておけばRedisサービスやサーバーの再起動を行ってもデータを保持しておくことができます。

・Pub/Subを使った仕組みを実装したい。

メッセージのやり取りをする仕組みのモデルとして”Pub/Sub”というものがあるのですが、Redisではこのモデルにのっとった仕組みを標準で提供してくれるようです。

Pub/Subモデルを使用したシステムを作りたい場合は、最適な選択肢になるかもしれません。

このように、システムによっては従来にない便利な仕組みを提供してくれるRedisですが、注意しなければならないのはRedisが”インメモリDB”であるという点です。

メモリ(RAM)上ででデータの保持を行う仕組みのため、メモリの容量の限界を超えたデータの保存は行うことができません。(記事によってはRAM全容量の約半分以上は保存できない、という話も記載されています。)

そのため、万が一容量がいっぱいになってしまった場合は、書き込み失敗とするか、古いデータを削除する以外に方法がありません。

データを永続させられるとは言え、Redisに置いておく必要のなくなったデータは積極的に削除するか、完全に永続化が可能なRDBやファイルなどに移しておくなどの工夫が必要となりそうです。

実際のところ、RedisはRDBを置き換えるのではなく、DBとアプリケーションの間に+αで追加することで、より高速な動作を可能にする使い方に最も効果がありそうです。

調べていてかなり興味がわいてきたので、是非一度Redisを使ったシステムも作ってみたいですね。

参考記事:
RedisとElastiCacheを分かりやすくまとめてみた – Qiita

Redisのメモリ検証 – Qiita

  • この記事いいね! (0)