DBの機能を持つことは、スケーラビリティへの障害ですか?


17

質問に正しいタイトルを付けることができない場合があります。しかし、ここにあります、

資産管理のための金融ポータルを開発しています。10000以上のクライアントがアプリケーションを使用することを期待しています。ポータルは、株式市場のテクニカル分析に基づいて、さまざまなパフォーマンス分析を計算します。

データベースを介して、ストアドプロシージャ、ユーザー定義関数、トリガーなどを通じて多くの機能を開発しました。C#コードを使用するよりも、データベースで直接作業を行うことで、パフォーマンスを大幅に向上できると考えました。そして、実際にパフォーマンスが大幅に向上しました。

CTOの功績について自慢しようとすると、コードではなくデータベースに機能を実装するという私の決定に疑問を呈しました。彼によると、そのようなアプリケーションにはスケーラビリティの問題があります。彼の言葉では「最近のものはメモリ/キャッシュに保存されます。クラスター化されたデータは時間の経過とともに管理するのが難しくなります。また、機能はデータベースから完全に分離する必要があります。」

彼の言うことが正しいかどうかについて、いくつかの提案をお願いします。そのようなアプリケーションを設計する方法は?


3
「実際にパフォーマンスが大幅に向上しました」と比べてどうでしょうか?クライアントに同じ機能を実装したことがない場合、どうやって知っていますか?
Doc Brown

3
プロジェクト、データの実装、チームのスキルに依存します。
ダニエルイアンコフ

1
CTOに、データベースが彼の好む手法を使用していないと考える理由と、ストアドプロシージャが「コード」として適格でない理由を尋ねる必要があります。
-Blrfl

3
FacebookとGoogleは、ほとんどのアプリケーションとはまったく異なる規模で問題を抱えています-市場からのデータに関して扱う必要があるデータの量に問題があるかもしれませんが、現代のSQLデータベースは膨大な量のデータに対処するために構築されています。
マーフ

1
彼のソリューションのパフォーマンスが不十分であり、それを管理する他の方法がなかったことを証明できない限り、おそらくCTOと同じ方法だと思います。ストアドプロシージャは、特にその数が大きくなると、必要に応じて他のDBに移動するための途方もない障壁を引き起こします...将来を予測できません。
リグ

回答:


23

要するに、私はあなたのCTOに同意します。おそらく、スケーラビリティを犠牲にしてある程度のパフォーマンスを得ることができます(これらの用語がわかりにくい場合は、以下で明確にします)。私の2つの最大の心配は、保守性と水平方向に拡張するオプションがないことです(あなたがそれを必要としていると仮定して)。

データへの近接性: 一歩後退しましょう。DBにコードをプッシュする理由はいくつかあります。最大のものはデータに近いことだと主張します-たとえば、計算が少数の値を返すと予想しているが、これらが何百万ものレコードの集約であり、何百万ものレコードを(オンデマンドで)送信する場合他の場所に集約されるネットワークは非常に無駄が多く、システムを簡単に停止させる可能性があります。そうは言っても、データの近接性を他の方法で実現できます。基本的には、キャッシュまたは分析DBを使用して、集計の一部を事前に行います。

DB内のコードのパフォーマンス:「実行計画のキャッシュ」などの二次的なパフォーマンスの影響を議論するのはより困難です。間違った実行計画がキャッシュされた場合、キャッシュされた実行計画は非常に否定的なことがあります。RDBMSに応じて、これらを最大限に活用できますが、ほとんどの場合、パラメーター化されたSQLをあまり使用しません(これらのプランも通常キャッシュされます)。また、ほとんどのコンパイルされた言語またはJITされた言語は、基本的な操作および非リレーショナルプログラミング(文字列操作、ループなど)について、通常は同等のSQL(T-SQLやPL / SQLなど)よりも優れたパフォーマンスを発揮するため、 JavaやC#のようなものを使用して数値計算を行った場合、そこに何かを失うことはありません。きめ細かい最適化も非常に困難です-DBでは、多くの場合、唯一のデータ構造として汎用Bツリー(インデックス)を使用します。公平を期すために、実行時間の長いトランザクションやロックのエスカレーションなどを含む完全な分析は、本を埋める可能性があります。

保守性: SQLは、その目的のために設計された素晴らしい言語です。アプリケーションロジックに最適かどうかはわかりません。私たちの生活を耐えられるものにするツールとプラクティスのほとんど(TDD、リファクタリングなど)は、データベースプログラミングに適用するのが困難です。

パフォーマンスとスケーラビリティ:これらの用語を明確にするため、私はこれを意味します。パフォーマンスとは、単一の要求がシステムを通過する(そしてユーザーに戻る)ことを期待する速度です。これは、多くの場合、通過する物理層の数、それらの層の最適化などによって制限されます。スケーラビリティとは、ユーザー/負荷の増加に伴ってパフォーマンスがどのように変化するかです。中/低​​のパフォーマンス(たとえば、リクエストに対して5秒以上)がありますが、素晴らしいスケーラビリティ(何百万人ものユーザーをサポートできる)があります。あなたの場合、おそらく良いパフォーマンスが得られますが、スケーラビリティは物理的に構築できるサーバーの大きさによって制限されます。ある時点で、その制限に達して、シャーディングのようなものに向かわざるを得なくなります。シャーディングは、アプリケーションの性質によっては実行できない場合があります。

時期尚早の最適化: 最終的に、時期尚早に最適化するという間違いを犯したと思います。他の人が指摘したように、他のアプローチがどのように機能するかを示す測定値は実際にはありません。さて、理論を証明または反証するために常に本格的なプロトタイプを構築することはできません...しかし、一般的に、パフォーマンスのために保守性(おそらく最も重要なアプリケーション品質)を犠牲にするアプローチを選択することを常にためらいます。

編集:肯定的なメモでは、場合によっては垂直方向のスケーリングがかなり遠くまで伸びることがあります。私の知る限り、SOは単一のサーバーでかなり長い間実行されていました。1万人のユーザーにどのように一致するかわかりません(システムで何をしているのかによって異なります)が、何ができるのかがわかります(実際には、より印象的な例、これはたまたま人々が簡単に理解できる人気のあるものです)。

編集2:他の場所で提起されたいくつかのことを明確にし、コメントするには:

  • 再:原子の一貫性-ACIDの一貫性は、システムの要件である可能性があります。上記は実際にはそれについて議論していません。ACIDの一貫性は、すべてのビジネスロジックをDB内で実行する必要がないことを理解する必要があります。そこにある必要のないコードをDBに移動することにより、DBの残りの物理環境で実行するように制約します。DBの実際のデータ管理部分と同じハードウェアリソースを奪い合います。コードだけを他のDBサーバーにスケールアウトすることについて(実際のデータではありません)-確かに、これは可能かもしれません、ほとんどの場合、追加のライセンスコストを除いて、ここで正確に何を得ていますか?DB上にある必要のないものは、DBから離して保管してください。
  • Re:SQL / C#のパフォーマンス-これは興味のあるトピックのようですので、議論に少し追加しましょう。もちろん、DB内でネイティブ/ Java / C#コードを実行できますが、私が知る限り、それはここで議論されたものではありません-T-SQLのようなものとC#のようなものの典型的なアプリケーションコードの実装を比較しています。過去にリレーショナルコードで解決するのが困難であった多くの問題があります。たとえば、「最大同時ログイン」問題を考えてみてください。ログインまたはログアウトを示す記録と時間があるので、一度にログインしたユーザーの最大数はそうでした。最も簡単な解決策は、レコードを反復処理し、ログイン/ログアウトが発生したときにカウンターを増分/減分し、この値の最大値を追跡することです。五月、わかりません)、あなたができる最善はCURSORです(純粋にリレーショナルなソリューションはすべて複雑さの異なる順序にあり、whileループを使用してそれを解決しようとするとパフォーマンスが低下します)。この場合、はい、C#ソリューションはT-SQLで達成できる期間よりも実際に高速です。それは大げさなように思えるかもしれませんが、この問題は、相対的な変化を表す行を操作していて、それらのウィンドウ集計を計算する必要がある場合、金融システムで簡単に現れます。ストアドプロシージャの呼び出しも高価になる傾向があります-些細なSPを100万回呼び出し、C#関数の呼び出しと比較してください。私は上記の他のいくつかの例をほのめかしました-T-SQLで適切なハッシュテーブル(実際にはいくつかの利点を提供するもの)を実装している人はまだいませんが、C#では非常に簡単です。繰り返しになりますが、DBが優れている点と、それほど優れていない点があります。C#でJOIN、SUM、およびGROUP BYを行いたくないのと同じように、T-SQLで特にCPUを集中的に使用するものは書きたくありません。

データベースに機能をプッシュする傾向がある理由の1つは、アプリケーションレベルのコードよりもバグが少ないことです。SQLは宣言型であり、命令型言語が抱える多くの問題に悩まされていません。
wobbily_col

保守性に関して、SQL Server Data Toolsの保守性の使用は簡単です。事実、重要なデータベース(5つ以上のテーブルを持つデータベース)については、それを要件と見なします。
Jon49

4

スケーラビリティは、データが置かれている場所や計算の方法とは関係ありません。スケーラビリティとは、グローバルな状態とデータの相互依存を管理する方法のすべてです。アーキテクチャがあらゆる種類のデータの相互依存関係を複雑にしている場合、そのデータを変換するためのコードをどこに置くかは関係ありません。相互依存関係は、あなたの手を強制し、スケーリングの可能性を減らします。一方、データが疎結合であり、グローバルステートがほとんどないかまったくない場合は、計算がどこで発生するかは関係ありません。物事のスケーリングははるかに簡単になります。

あなたのCTOがスケーラビリティの問題に関する彼の情報をどこから得ているのかはわかりませんが、あなたが言ったことから、彼はソフトウェアのファッショントレンド以外の現在のアーキテクチャの決定を疑問視する本当の理由があるようには聞こえません。このような傾向に基づいてアーキテクチャ上の決定を下すことは、通常、悪い考えです。


1
+1Scalability is all about how you manage global state and data inter-dependence.
エステファニーヴェレス

2

そして、実際にパフォーマンスが大幅に向上しました。

パフォーマンスベンチマークを設定し、最初にプロトタイプの構築を開始する必要があると思います。DBですべてのロジックを保持することは、クライアントサーバーアーキテクチャを扱う古いやり方です(私見では、これに反対するものはありません)。それには利点がありますが、考慮すべき多くの欠点があります。

このタイプの販売可能なアプリケーションの通常のアプローチは、SOAを介して行われます。長い目で見れば、これがプロジェクトに新しいクライアントアプリケーションを追加する最も簡単な方法だからです。

トリガーについて言及しました。トリガーの使用は、アプリケーションのサポートライフサイクルの後半で大きな落とし穴になる可能性があります。私はそれを二重に注意し、その使用をスキップしようとします。


2

CTOが100%間違っています。

財務番号常に合計する必要があります。つまり、ACIDが必要であり、リレーショナルDBがそれを保証する最適な場所です。NoSql DBのパフォーマンス向上は通常ACIDの費用であり、GoogleとFacebookでは問題ありませんが、財務を含むシステムでは問題ありません。

C#のパフォーマンスがSQLコードよりも優れていると言うのも、馬鹿げています...


SQLコードよりもC#のパフォーマンスが優れていると言うのも愚かです… -しかし、C#コードがよりスケーラブルであることを否定しているわけではありません。
ジムG.

ボトルネックがない場所ではないため、SQLコード(データではなく)を水平方向にスケーリングできます。C#コードを水平方向にスケーリングできるのと同じくらい簡単です。
モロン

@JimG。明確にするために、「SQLコード(データではなく)を水平方向にスケーリングできるのは、C#コードを水平方向にスケーリングできるのと同じくらい簡単だ」ということです。C#と同じようにスケーリングする必要があります。C#の方が優れていると言うことはできません。言語ではなく計画の問題です。
モロン

@JimG .:スケーリングしないソフトウェアは、C#を含む任意の言語で作成できます。その価値のあるデータベースは、ネイティブのSQL風の実装以外の言語で記述されたストアドプロシージャを持つことができ、ACIDを必要とする状況でNoSQLを使いこなす人々は通常、うまく機能しているホイールのほとんどを再発明することになりますDBMSによって実装されます。
Blrfl

@Morons:私たちは同意すると思います。私はだった「SQL」を使用してデータをconflating実際に。データベースのスケーリングははるかに高価です。
ジムG.

2

誰もがスケーラビリティやGoogle / Facebook / Twitter /などに言及するときはいつでも、それはニシンです。基本的に同じサービスを提供しているのでない限り、それらで機能するものは適切ではないかもしれません。一般に、1台のマシンから8台のマシンのクラスターにスケールできる場合は、おそらくすべてのベースをカバーしているでしょう。1日に2,000万ページビューを提供するという厳しいビジネス要件がない限り、ハイパースケーリングについて心配する必要はありません。アプリケーションの実際の要件に合ったものを実行し、必要になったことが明らかになったときにスケールアップを心配します。また、ほとんどのデータベースサーバーもクラスター化できることを忘れないでください。そのため、すべてが1つのデータベースにあるからといって、1つのサーバーにあるとは限りません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.