質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

  • PHP

    21373questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    6197questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

チャットシステムにおけるデータベースとの最適な通信方法

解決済

回答 8

投稿

  • 評価
  • クリップ 2
  • VIEW 1,170

Tololololo

score 88

チャットシステムのような非同期通信を何度も行うシステムについてです。

言語はPHP、DBはMySQLを使う予定です。

データ送信者がDBにデータを送り、受け取り側に対して「このデータを取得せよ」というようなやりとりを行うために、インターバルを設けてその時間ごとにDBから最新情報を取得させるのは最適ですか?

自分がよく使うチャットシステムは送信者がメッセージを送信すると1~3秒後ほどでメッセージを受け取ります。(チャット画面を開いている状態を維持しています。逆に閉じている状態であれば再度表示時に取得させるようにすれば良いので)

このインターバル方式の場合、同じように3秒ごとに取得するような通信をさせるとサーバーの負荷が心配です。
(一応自分のサーバーは5000GBまで耐えられるようにはなっています。)
しかし、今の自分の知識ではインターバル方式以外考えつきません。

他にこういったチャットアプリの最適な通信方法はありますか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 8

+3

インターバルを設けてその時間ごとにDBから最新情報を取得させるのは最適ですか? 

the most であるかと文字通り解釈すれば、その限りではありませんとなります。
WebSocket で実装する方法もあります。

このインターバル方式の場合、同じように3秒ごとに取得するような通信をさせるとサーバーの負荷が心配です。
(一応自分のサーバーは5000GBまで耐えられるようにはなっています。)

「5000GBまで耐えられる」どう言う意味なのか…たんにHDDの容量と考えられる大きさのようですが、HDDの容量をもって「耐えられる」と言うのはピントがずれてます。容量はむしろパフォーマンスに関してはほぼ影響ありません。

例えば、3秒に一回りクエストされるといっても1ユーザーのリクエストの話。ユーザーが100人いれば、秒間平均33回のリクエストがあるということになります。
そうなると、1リクエストあたり、10秒かかる処理となるとどんどんリクエストが処理待ちになって処理されないリクエストが発生してくるでしょう。
例えると、お店の前にどんどん行列ができて、お店に入れない人が出てくるようなイメージです。
これはDBの処理やプログラムの性能によるものです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+2

他の方の回答を見ましたが、キーワードベースの回答が多いので、少し解説を入れて回答してみたいと思います。

インターバルを設けてその時間ごとにDBから最新情報を取得させるのは最適ですか?

だめです。
一定時間ごとのポーリングではデータが無くてもサーバ側で処理が発生することになり、CPUもネットワーク資源も無駄になります。データが発生したときにだけサーバ側の処理を実行するよう、クライアントに対してプッシュで通信することを考えてください。Webの場合、クライアントに対してプッシュで通信しようとすると、 comet か websocket になります。今なら WebSocket で良いのではないでしょうか。

言語はPHP

チャットシステムを作るのであれば、イベント駆動型のアーキテクチャで組む必要があり、リクエストごとにスレッドを専有してしまう PHPは不向きです。 Go, erlang, lua のような軽量スレッドの言語か javascript のような非同期処理対応の言語で開発する必要があるでしょう。
node.js をおすすめします。

「リクエストごとにスレッドを専有してしまう」ことがなぜだめなのか、例をあげて説明しましょう。
チャットで誰かが発言すると、

  1. その内容をDBに書き込んで、
  2. 会話相手にメッセージをプッシュで配信

という処理を行うとします。 PHP の場合この処理に対してスレッドが割り当てられます。すると、DB に書き込んでいる間、メッセージをプッシュで配信している間そのスレッドは待ち状態になります。
この待ち状態のスレッドが多数できると、メモリを圧迫し、コンテキストスイッチ(スレッドを切り替える処理)の負荷が高くなって性能が低下します。
これは c10k(connection 10000=1万接続)問題と呼ばれていて、リクエストを受け付けたスレッドを開放して非同期に処理するのが常套手段となっています。
node.js で javascript で組めば、(syncXXのような特別なものを使わなければ)常に非同期でコーディングさせられるので、 c10k 問題を気にする必要はありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

そもそもリアルタイムに反応するチャットシステムと、php+MySQL は相性があまり良くないです。
firebase 等を検討してみては?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

同じように3秒ごとに取得するような通信をさせるとサーバーの負荷が心配です。

既に取得してたら空振りさせればいいのでは。

実際に作ってみて分かることもあるでしょうし。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+2

いまお手軽にリアルタイムメッセージングアプリ作るなら、firebaseでRealTimeDB使うか、Firestoreですかね。
サーバレスでやろうと思えばできるし、無料枠でも全然いけると思います。
MySQLにこだわりがないのであればその辺ですね。
MySQLでやりたい、ってことであればとりあえず負荷を気にせずにやってみるのがいいと思います。
リアルタイム性を求めるなら、普通に考えるとWebsocketなので、その場合PHPだとつらいんでNodeになると思います。
PHP+MySQLがいいってことであればWebSocket使わずにインターバル?(ポーリンングかな)でやってみて、負荷が気になるようになってきたらまた別途Redis挟むなり、Shardingするなりで負荷対策考えればいいと思います。
PHP+MySQLってのがWebアプリやってみる上で情報多いと思いますが、それを使ってちゃんとしたチャットアプリ作るのは実はハードル高いです。(相性が悪い)
がんばってください!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

自分だったら、利用者が10人程度までなら、どんな仕様でも実装してみるかな
高負荷になってどこかに影響が出るようなら出来た後に何かしら対策を考える

Webサービスとして一般化する場合は悪用されることも考えないとならないから、安易な実装は自殺行為だろうけど
趣味としてなら、トライアンドエラーはプログラミングの理解度を上げるにはもってこいの素材だと思う

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

以下キーワードで検索し順次実装をテストしてください

  • javascriptポーリング
  • ピギーバック
  • Comet
  • ロングポーリング

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

チャットかどうかではなく通信量を先に考えますd^^
一般の商用回線では100MBPSが一般的だと思いますが、10Mバイト/secで考えると1Kバイトのデータのやり取りが1万回/秒出来ることになります。・・・ではどうするか
受信側/送信側にキューを持って受信するスレッドは受信データが発生したらそれをキューに入れる。送信側は送信データが発生したらそれを送信する。・・・仕事にだけ集中させます。(機能を最小限にする)
処理を行う側は受信キューにデータがあれば、それ用のスレッドをお起こして受信キューから受信データを取り出して処理を行い、送信データを送信キューに入れてスレッドを終了する。・・・全て非同期となるため排他制御は必須d^^ それだけの処理を行って問題の起らない環境(OS,DBサーバや開発環境等)を選択する。これならば、もし1万件/秒以上のリクエストが来ても回線がネックになるので負荷は変わりません。・・・私ならOSはFreeBSD(負荷に強い)、DBはte2jiさんがおっしゃるfirebird(1億ぐらいのレコードであれば問題なく使える)、開発はGCC(clang)あたりを使うと思います。(負荷がそれほどないならjava、PHPもありか?)・・・フリーに限定しちゃってますv^^;

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    21373questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    6197questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。