Webアプリのセッション管理とデータ保存を学ぶ#3(社内勉強会)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。Webサービスにおけるデータ保存(サーバーサイド編)続いてサーバー側でのデータ保存について説明します。ほとんどのWebサービスでは、最終的なデータをサーバーのどこかに保存しておかなければなりません。Webサーバーは多数のクライアント(及びユーザー)から同時にアクセスを受けるため、それらを個別に処理して、矛盾が生じないように保存する必要があります。サーバー側でのデータ保存の種類について以下で説明します。ファイルに保存する最も単純な方法であり、手軽に作成されたフォームプログラムなどではCSVファイルなどから設定情報を読み取り、データ保存もサーバー側のCSVファイルなどに書き出すといった作りをすることがありますファイルへの保存は最も手軽に行える方式ですが、同じファイルに完全に同時書き込みが発生したときに問題が発生する可能性が常につきまといます。OS側でのファイルロックで書き込みや読み出しに失敗することもあれば、ファイルのデータそのものが破損する可能性もあります。ファイルへの保存は、更新の不要なデータを読み取り専用で使うのが無難です。morimorihoge注)もちろんファイル保存形式でも、ロックファイルなどの伝統的な排他制御を実装することで、データの保全を行うことは可能です。※著名なオープンソースソフトウェアでファイル保存形式を利用しているものは、ちゃんと排他制御が実装されていることがほとんどですただ、真面目にきちんとした排他制御をファイルベースで行う場合、ロックファイルの消し忘れ対策などの問題が残る上、ある程度大量のアクセスを捌ける様にするにはOSのファイルAPIや作法に対する知識も必要になってくる(セッションごとの一次データはtmpfsに置きつつ、書き込み時は共通のデータファイルに追記モードで書き込むことでなるべくロックを避けるなど)ため、ちゃんと作ろうとすればするほど元々ファイル保存の魅力であった「お手軽簡単」というところから離れていきます。いうわけで、ほとんど同時アクセスの来ないようなユースケースを除き、ファイルに全ての情報を保存する方法は昨今あまりオススメできません。データベースに保存するRDBMSなどの専用データベースシステムは、Webアプリのデータ保存先の主流となっています。Web系のソフトウェア開発の世界では、データベースというと多くの場合場合RDBMSを指します。データ書き込みの排他処理やトランザクション処理を確実に実行できることでデータの矛盾を回避できます。データベースには、RDBMSなどのWebサーバーとは独立したシステムを使うことがほとんどなので、サーバー側に別途RDBMSをインストールする必要があります(最近ではクラウドのデータベースサービスを使うことも増えています)。Object)ライブラリなどを使うことで、単純な利用用途の範囲であれば避けて通ることも可能ではあります。Serverなどがよく使われます。RailsではPostgreSQLやMySQLがよく使われます。SystemRDBMSについては本勉強会の範疇を超えるのでごく簡単にとどめますが、Webアプリ開発においても重要な機能を担っています。RDBMSは、リレーションモデルを基礎として、行(row)と列(column)からなるテーブル(table)という表形式のデータを扱います。RDBMSでは、以下を実現することで安全・高速・正確にアクセスする機能を提供します。一貫したデータ構造の管理RDBMSの「ACID」RDBMSのこうした機能の実現に必要な4つの要素(性質)は、その頭文字を取ってACIDと呼ばれます。どちらかの状態だけを取ることConsistency(一貫性・整合性)トランザクションの前後での整合性を維持することIsolation(独立性・隔離性)変更中の内部データを隠蔽することDurability(永続性・持続性)処理の完了したデータが障害によって消えず復元可能であること「NoSQL」という選択肢データベースには、上述のRDBMSの他に「NoSQL」と称されるデータベースシステムもあり、用途によって使い分けられます。NoSQL系のデータベースシステムでは、RDBMSと異なり、上述のACIDの一部(またはすべて)が保証されないので注意が必要です。NoSQL系は各々が得意とする特定のユースケースにおいてはRDBMSよりも高性能ですが、ACID特性が犠牲にされるため、キャッシュやPub/Sub(Publish/Subscribe)のように永続化やデータの整合性よりも速度を重視する場面で使うことがあります。store)の一種ですが、現在はそれ以上の機能が追加されていることもあり、RDBMSが不得意な部分(キャッシュやPub/Sub、ランキングなどの高速な集計)を補う用途で導入されることが増えています。MongoDBやDynamoDBなどのドキュメント指向データベースは、データ構造の自由さという使い勝手の良さも相まってひと頃人気を博しましたが、RDBMSとは別のノウハウが必要だったり、ACID特性の必要な場面で誤って使われることもあったためか、最近ではやや落ち着いているようです。morimorihoge注)昨今ではRedisやらMongoDBやらといったNoSQLがもてはやされる風潮がありますが、特に初学者の人は惑わされてはいけません。世の中のアプリケーションで最も使われているのはRDBです。RDBを使いこなしましょう。NoSQLがRDBの苦手な特定用途の問題を解決するのに役に立つのは確かですが、RDBも進化しているため多くのユースケースはRDBでカバーできます。まともなRDB設計ができれば基本的には百万レコードくらいまではほぼチューニングなしでそれなりの実効性能が出せることが多いですし、それ以上になってきてもRDB側のチューニングや適切なDB設計で大抵のユースケースに対応できます。僕の経験則ですが、RDB以外にデータを保存するのが妥当なケースは以下のケースなどが挙げられます。S3を始めとするオブジェクトストレージに入れる方が良い。RDBにバイナリとして入れることもできるが、サイズが大きくなりすぎるのでメンテ上もデメリットの方が多い。コンテンツキャッシュデータの保存RedisやMemcachedなどのとにかくI/Oが早いKVSを使う方が良い。RDBの備えるACID特性(後述)の多くが不要。KMSなどの鍵管理のためのシステムに入れる方が管理上事故が起こりにくいです。ユーザー側機密情報は検索したいケースなどもあるのでRDBに入れる方が開発は楽になります。短いレイテンシと高いスケールアウト性が求められる場合、RDBだとポーリングが辛いのでRedisのPub/Sub機能やRabbitMQなどのメッセージサーバー、または簡単なPub/Sub機構であればNode.jsやGolangで参考実装があると思うのでそういったものを使う方が良いと思います。不定形ドキュメントデータの保存MongoDB・・・という手もありますが、MongoDBはノウハウがないと色々と辛い話も聞くので、PostgreSQLのJSON型で足りるのであればそちらの方が良いと思っています。Solrなどの全文検索に特化したものを使う必要があります。何にせよ、まずはRDBを使いこなした上で他の保存形式に手を出す方が実用的なので、上記の例に該当するようなケースを除けばデフォルトはRDBMSを使う、くらいに考えておくのが良いと思います。データの保存先はアプリケーションが育ってくるとそう簡単に切り換えられません。安直に選ぶと将来に渡って辛い技術的負債を残すことになるので、慎重に検討しましょう。Web開発初心者向けのデータ保存シナリオWebアプリでのデータ保存については、さしあたって以下を目安に考えるとよいでしょう。セッションID以外のものは極力保存しないCookieはセッションIDの保存にのみ使うのがポイントです。それ以外の値も追加で保存したくなった場合には、本記事にあるような欠点を考慮した上で利用しましょう。※秘密キーや多言語文言などについてはまた別の機会とします。キャッシュ目的などを別にすれば、NoSQLは原則としてメインのデータベースの検討対象から外れます。RDBMSのフル機能がなくてもよく、かつ次のような特定の要件に該当する場合は、詳しい経験者に相談のうえで検討しましょう。Storageがあります。Cookieの利用はセッションIDの保存にとどめましょう。サーバー側のデータ保存には、原則としてRDBMSを用います。それ以外のNoSQL他の利用については慎重に検討した上で利用しましょう。コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。enno.jpを運営。実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。