6000株の10Mドキュメントのコレクションがあり、株名は索引付けされています。新しい株を購読すると、この株の約 3000 のドキュメントを取得するのに meteor が 10 秒以上ハングします。また、いくつかの株式をサブスクライブした後、Meteor が 100% の CPU 使用率でハングします。Meteor は、「大きな」コレクションを同期すると非常に遅く見えます。実際、私のアプリは読み取り専用です。読み取り専用クライアントの流星を高速化する方法があるかどうか疑問に思っていますか? また、在庫ごとに個別のコレクションを作成すると役立つかどうかも疑問に思っていますか?
5 に答える
Meteorはデータセット全体をクライアントにプッシュしています。
自動公開パッケージを削除すると、自動公開をオフにできます。
meteor remove autopublish
次に、クライアントに固有の特定のサブスクリプションを作成します。
サブスクライブするときは、セッション変数を引数として渡すことができるため、クライアントでは次のようにします。
sub = new Meteor.autosubscribe(function(){
Meteor.subscribe('channelname', getSession('filterval'));
}
サーバーでは、引数を使用してクライアントに送信される結果セットをフィルタリングし、すべてを一度にパイプ処理しないようにします。フィルタを使用して、何らかの方法でデータをセグメント化します。
Meteor.publish('channelname', function(filter){
return Collection.find({field: filter});
}
これで、サブスクリプションを使用してクライアントでfiltervalを変更するsetSession('filterval', 'newvalue');
と、自動的に変更され、新しいデータセットがクライアントに送信されます。
これは、クライアントに送信されるデータの量と量を制御する手段として使用できます。
別のポスターが言ったように、あなたはこれがこの仕事に最適なツールであるかどうかを本当に尋ねなければなりません。Meteorは、(潜在的に)2つの方向にリアルタイムで更新される比較的小さなデータセットを対象としています。高度に最適化されており、そのユースケース向けに大量の足場があります。
別のユースケース(読み取り専用の巨大なデータセットなど)では、意味がない場合があります。使用しない機能を提供するオーバーヘッドが多く、必要な機能を取得するためにコーディングすることになります。
私は同じ問題に苦しんでいました。私の場合、約 30KB の合計 3000 件のレコードを同期するだけで済みました。数週間試した後、最終的に同期が問題ではなく、同期中に発生した LiveHTML の更新に問題があることに気付きました。
最初のページの読み込み中にテンプレートの更新を無効にすることで、ページの読み込みを 300 件の (フィルター処理された) レコードで 10 秒から 3000 件のレコードすべてで 2 秒未満に短縮できました。テンプレート コンテンツを定義する関数に条件を追加することで、これを実現しました。
前 (サーバーによって公開される 300 レコードの 10 秒のページ読み込み):
Template.itemlist.items = function () {
return Item.find({type: 'car'},
{sort: {start: -1},
limit: 30});
};
に (サーバーによって公開された 3000 レコードの 2 秒のページ読み込み):
Template.itemlist.items = function () {
if (Session.get("active")) {
return Item.find({type: 'car'},
{sort: {start: -1},
limit: 30});
} else {
return [];
}
};
データが読み込まれたときにのみセッションを「アクティブ化」するには、次のように追加しました。
Deps.autorun(function () {
Meteor.subscribe("Item",
{
onReady: function() {
Session.set("active", true);
}
});
});
これは規模の問題であり、おそらく改善できます。Meteor はクライアント間のやり取りを目的としており、読み取り専用の時間依存データを大量に取得するためのものではないため、タスクに間違ったテクノロジを使用していることに注意してください。ステータス追跡画面はまだある程度理にかなっているかもしれませんが、大量のタイムクリティカルなデータは確かにそうではありません...
Meteor スタック全体は、ネイティブ スタックでの単純な実装に比べて極端なオーバーヘッドをもたらします。正直なところ、Java や C# が導入するオーバーヘッドを考慮に入れ、それと PHP や C++ などの低レベル言語のどちらを選択するかについてよく考えます。Ruby、Python、Node.js などの言語はまったく別の話です。それらはラピッド プロトタイピング用に作られていますが、レイテンシー/スループットの点では、JIT にかかるオーバーヘッドのために遅れています。
TL;DR :仕事に適したツールを使用しないと、指を切ることになります...
自動公開を有効にすると、Mongodb の大量のドキュメント コレクションでパフォーマンスが低下することがあります。自動公開を削除し、コードを記述して、データベース全体ではなく関連データのみを公開することで、これに対処できます。
ドキュメントはキャッシュを手動で管理することにもなります:
洗練されたクライアントは、サブスクリプションのオンとオフを切り替えて、キャッシュに保持するデータの量を制御し、ネットワーク トラフィックを管理できます。サブスクリプションがオフになると、同じドキュメントが別のアクティブなサブスクリプションからも提供されていない限り、すべてのドキュメントがキャッシュから削除されます。
「非常に多数のクライアント」をサポートするための DDP レベルのプロキシなど、Meteor の追加のパフォーマンス改善が現在取り組んでいます。詳細については、Meteorロードマップを参照してください。
私は流星のシンプルさが大好きです。同期のオーバーヘッドを避けるために、ローカルの mongodb コレクションの使用をやめただけです。パフォーマンスは非常に良さそうです。
Meteor.default_connection.registerStore "prices",
beginUpdate: ->
update: (msg) ->
updateChart(msg.set)
endUpdate: ->
reset: ->
新しい隕石の場合、以下が機能します。
Meteor.default_connection.registerStore collection,
constructor: (@update) ->
# Called at the beginning of a batch of updates.
beginUpdate: ->
update: (msg) ->
update(msg.fields, msg.id) if msg.fields
endUpdate: ->
reset: ->