2016年02月12日

Prarallel構文を使ってタスクによる並列化を考える


先日、プログラム高速化の要望があったので、マルチコアCPUを使って、並列処理ができないか検討してみました。

C# で WinForm アプリケーションを書いていると、UI スレッド(フォアグラウンド)から、バックグラウンドスレッドに処理を任せても、バックグラウンドからは直接UIスレッドを触れないという問題に出くわしたりしますが、この別スレッドで動く仕組みを使うと、並列に処理を進めることができます。

このスレッドという仕組みは、同じメモリ空間にありながら、独立したスタックを持つことで並列に動くことができるわけですが、スレッドの生成、消去には、時間がかかります。そこで、あらかじめ用意したスレッド・プールに、小さな並列に動くプログラム断片を放り込んで、順番にスレッドとして動かす仕組みが作られました。(ここの詳しい説明は、スレッドプールとタスク がわかりやすいです。)

この小さなプログラム断片を Task と呼びますが、扱いにくいスレッドを抽象化して、C# から扱いやすくしたものと考えればいいと思います。こうしてスレッドプールをCPUのコア数程度用意すれば、Task を意識してプログラムを作るだけで並列度があげられそうです。従って、今後は、スレッドという用語に惑わされずに、Task で考えていくのがいいのでしょう。。。

この考えにマッチしているのが、Parallel 構文の For, ForEach, Invoke で、割と簡単に並列動作可能なプログラムが作れるようになります。これらの構文では、ラムダ式、関数呼び出しなども組み合わせられます。さらに、Async, Await という、非同期制御が書きやすい構文も追加されているので、これらを組み合わせれば、複数のCPUコアを効率よく使えそうです。いくつか実験的なプログラムを書いてみて気が付いたことですが、、

  • Task 同士が実行途中で共有変数を更新するようなロジックはなるべく考えない方がよい。(ロックが発生して、並列度が下がります。)

  • Task があまりに小さいと、Task 切り替えの時間が無視できないサイズになり、Parallel構文を使わない方が速くなってしまう。いろいろ試行錯誤してみましたが、ある程度以上のサイズにしないと並列化したメリットがでませんでした。

  • スレッドセーフなクラスの使用を優先する。

  • どこを並列化したらいいか考慮しながら設計する。


posted by 開発G at 11:33| Comment(0) | TrackBack(0) | Programming

2016年02月07日

SQLServer の .dacpac と .bacpac の使い分け

SQLServer を使っていると、DAC (データ層アプリケーション)という用語が出てきます。あまり意識したことはないのですが、要するに、テーブルや、ビューなど、データベースに関連づけられたデータ以外の論理的な仕組みのことだと思います。DAC という用語を使う場合は、テーブル内のデータであるレコードは含まないようで、DAC をファイルに出力した .dacpac を見ても、レコードは入っておらず、空のテーブル構造が保存されるだけでした。

実際のデータ、レコードも保存したければ、.bacpac という拡張子のファイルにエクスポートする必要があります。

Azure SQL と、ローカルの SQLServer の間では、.bacpac ファイルによってやり取りが可能です。その場合、直接 AzureSQL に接続しても、大きなファイルの場合は転送中に失敗することがあるので、一度、ストレージを経由した方が安心して作業を進められます。

posted by 開発G at 17:46| Comment(0) | TrackBack(0) | SQL

2016年01月29日

IE のドメインあたりのクッキー数には要注意


IE で Web アプリを動作確認しているときに、ログイン認証しているにもかかわらず、再度、ログイン画面に戻ってしまうことがありました。同じWebアプリでも、Chrome ではその現象が発生しないことから、IE に依存する問題と思い調査すると、使っているクッキー数が多すぎることが理由であることを突き止めました。おそらく、クッキー情報が切り捨てられることにより、セッション情報が捨てられてしまって、ログインしていないアクセスになってしまうのでしょう。

自分でクッキーを増やしていなくても、広告や、埋め込みスクリプトなどが、勝手にクッキーを追加していることがあります。特に、トラッキングなどの機能を追加している場合には、それらが独自のクッキーを追加するので要注意です。クッキー数を減らす努力をしたところ、セッション情報が消えてしまう現象は収まりました。

IE のクッキーにはいろいろな制限があるようで、次のような点に注意が必要です。

  • ドメインごとに 20 を超える cookie が存在する場合は、切り捨てられる可能性がある。

  • cookie 情報を連結して 4096 バイト以上になる場合は、切り捨てられる可能性がある。

等々、いろいろあるようです。

日本語訳が変なので、理解に苦しみますが、詳しくは、Internet Explorer 内の cookie の数とサイズの制限 を参照のこと。

posted by 開発G at 16:12| Comment(0) | TrackBack(0) | Web

2016年01月26日

SQLServer フェイルオーバクラスタ作成手順

SQLServer でフェイルオーバクラスタを作成する場合は、次のステップで実現します。

  • まず、2つ以上の Window Server マシン(ノードと呼ぶ)からなる クラスタを作ります。クラスタを作成するには、ActiveDirectory が必要です。
    そのうち1つ以上をアクティブとし、残りをスタンバイとする N+1 型を考えます。
    アクティブノードからの HeartBeat がなくなったら、自動的に、スタンバイ機に切り替わるような環境を、Hyper-V や、VMWare 等で作っておきます。

  • クラスタ全体に割り当てた仮想IP,ネットワーク名で参照するようにすれば、クラスタ内でアクティブサーバが変わっても、
    同じ名前で参照し続けられます。もちろん、各ノードには、それぞれ固有のIPアドレス、ネットワーク名が存在するわけですが、それらはメンテナンス時以外は使わないようにします。

  • アクティブ、スタンバイ、それぞれに SQLServer をインストールし、それらのSQLServer が共有できる 共有 DISK を用意します。
    共有 DISK の代わりにフォルダをマウントする機能も使うこともできます。
    共有DISK の冗長構成は別課題になるので、RAID や、バックアップ戦略を別途考える必要があります。

  • 共有ディスク上には、各データベースファイルと、トランザクションログを配置します。これで、ノードが切り替わったときでも、同じデータベースを動かし続けることができます。
    temp などの同期をとる必要のないデータについては、各ノードに配置することも可能です。


SQLServer の高可用性には、ここで示したフォールト・トレラントの他にも、ログ配布、ミラーリングと呼ばれる手法があります。
posted by 開発G at 08:02| Comment(0) | TrackBack(0) | SQL

2016年01月14日

Master ページの Initイベントと、Load イベントの呼び出されるタイミング

ASP.NET では、Masterページと、Content ページを組み合わせて Webページを開発することができますが、ページが表示される際に、どのような順序で初期化されるか悩んだことはありませんか?

悩んだ末に次のような順序でイベントが発生することがわかりました。Initと、Load で順序が違うんですよ。Init イベントは、外側から始まって、内側が呼び出されていき、Loadイベントは内側から外側に向かって呼び出されるという具合です。どこかの Window 関連イベントと似ています。


  • マスタ ページの Init

  • コンテンツ ページの Init イベント

  • コンテンツ ページの Load イベント

  • マスタ ページの Load イベント



実は、必要なのは、Init と、Load のタイミングだけだったのですが、内部のコントロールまで入れると
かなり複雑になるようです。

詳細は、次のページで確認できるんですが、日本語訳のページと、英語のページの内容が微妙に違っていてわかりずらいです。一応、Helpful じゃないとコメント入れておきました。

ASP.NET のマスター ページとコンテンツ ページのイベント


Events in ASP.NET Master and Content Pages
posted by 開発G at 23:26| Comment(0) | TrackBack(0) | ASP.NET