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

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

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

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

PHP

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

Q&A

解決済

8回答

9337閲覧

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

Tololololo

総合スコア118

MySQL

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

PHP

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

0グッド

3クリップ

投稿2018/07/16 12:12

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

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

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

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答8

0

ベストアンサー

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

インターバルを設けてその時間ごとに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 問題を気にする必要はありません。

投稿2018/07/17 10:08

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

このインターバル方式の場合、同じように3秒ごとに取得するような通信をさせるとサーバーの負荷が心配です。

(一応自分のサーバーは5000GBまで耐えられるようにはなっています。)

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

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

投稿2018/07/16 13:00

編集2018/07/16 13:02
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

投稿2018/07/17 09:25

miwata

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

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

投稿2018/07/16 13:18

m.ts10806

総合スコア80765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

投稿2018/07/16 12:58

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

投稿2018/07/17 06:51

yambejp

総合スコア114572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

投稿2018/07/16 13:30

efcode

総合スコア422

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

投稿2018/07/16 15:06

編集2018/07/16 19:27
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問