狠狠撸

狠狠撸Share a Scribd company logo
ソフトウェア方面の先進テクノロジー
~ Sansan 流の業務系アプリ開発者視点 ~
Sansan株式会社
藤倉 成太
? 弊社サービスSansanについて
? SansanにおけるOSSの活用事例
? Webフレームワーク
? PostgreSQL、Redisとクライアントライブラリ
? インフラ
今日話すこと
名前
藤倉 成太(フジクラ シゲモト)
仕事
Sansan 事業部 開発部部長
アーキテクト
2009 年 Sansan 入社
自己紹介
厂补苍蝉补苍についてまとめ
たとえば
RDB : Oracle / PostgreSQL / MySQL
NoSQL : Memcached / Redis / MongoDB / RavenDB
Web Framework : Nancy / ServiceStack
DI : Unity / Ninject
テスト: NUnit / NSpec / SpecFlow
ロギング : log4net / NLog / Fluentd
CI : Jenkins
さらに選択肢を増やす
Build Insider - 社内の開発環境の改善&効率化のためにNuGetを活用しよ
う
それぞれが作った、ちょっとしたツールやコードを
社内用NuGetリポジトリに、公開しましょう
.NETでも選択肢の数は変わらない
実績には注意
GitHubならWatchやStar、Issuesなどを確認する。
NuGetならDownloadsなども参考になる。
それらを踏まえて、リスクもきちんと評価した上での採用を。
バグは、ある
テストは十分に。
できればソースコードも読む。利用する箇所だけだったり、
軽く流し読みするだけでも安心感は違う。
ご利用は計画的に
Sansanについて
弊社事例が、皆様の会社での
OSS導入の一助になれば幸いです
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
名刺管理Webサービスを開発、運営
創業7年目で名刺管理に絞ったシステムを作っています。
名刺管理システム業界トップ。ちょっとだけCM流してます。
プロダクト
法人向け名刺管理Sansan
C# + ASP.NET + PostgreSQL
個人向け名刺管理Eight
Ruby on Rails + MySQL + AWS
Sansan株式会社について
ASP.NET上で動くWebアプリ
個人向けサービスに比較するとユーザ数はずっと少ない。
ソーシャルゲームなどでは100万人以上、Eightで50万人以上
Sansanは数万人、前職では数百人。
負荷
200万リクエスト/日を2台のWeb/Appサーバで。
突然跳ね上がることは滅多になく、平日の9-20時にアクセスが
集中。休日のアクセスはほぼ無い。
法人向けサービスSansanの特徴
データ
ユーザ数と比較すると、おそらくデータは多い。
1億超レコードのテーブルや、数千万、数百万レコードの
テーブルが数十。たとえば、名刺テーブルは2千万超レコード。
個人向けサービスのEightは1千万超レコード。
システムに求められる要件
可用性、一貫性、アクセスコントロールなどの要求は高い。
一方で、パフォーマンスは個人向けサービスに比べると緩い。
如何に速くするか、よりも如何に確実に処理するかが重要。
また、営業やサポート部署への影響にも配慮する必要がある。
法人向けサービスSansanの特徴
言語
C# 5.0 (.NET Framework 4.5)
Web/App
Windows Server 2008 R2 / IIS 7.5
キャッシュ/セッション
Redis
DB
PostgreSQL 9.1
インフラ
後述
Sansanの構成
生産性
創業当初の限られた人員でWeb/クライアント(※)/社内システム
全てを作る必要があった。
クライアントOSは最も一般的なWindowsをターゲットに、
Windows+高生産性=Windows Formsを採用するに至る。
スキルを応用できるし、という理由でWebも。
※スキャナと連携する名刺登録アプリケーション
なぜC#か
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
フレームワーク
プロダクトはWeb Forms/MVC/Web API併用。
社内ツールにNancy
Web/App
特別な使い方はしていないので
割 愛
Web Forms/MVC/Web API
軽量Web Framework
処理を一つのメソッドで記述。
HTTPメソッドごとルーティングを指定して処理を記述。
RubyのWeb Framework、Sinatraにインスパイア。
Nancy
require ‘sinatra’
get ‘/’ do
# do something
end
post ‘/’ do
# do something
end
Nancy
public class MyModule : NancyModule {
public MyModule() {
Get[“/page/{id}”] = param => {
// データ取得
var data = new DbClient().GetData(param.id);
// データ加工
var responceData = data.Select(_ => _.Value);
// データ表示
return View["page", new { Data = responceData }];
};
Post[“/regist”] = param => { // 省略 };
}
}
用途
ログの収集解析アプリで利用。
ASP.NET & Nancy & MongoDB
やりたかったこと
やりたい処理は単純なデータ取得 > LINQ+αで加工 > 表示。
将来も含めて、MVCを利用するほどに大げさなものではなく、
容易に保守できるような作りにしたかった。
Nancy
結果
一つのメソッドに処理が集まるので、自然とシンプルに実装する
ようになり、ルーティングも一目で分かるのでデバッグや保守が
非常に容易に。
とにかく気軽にAPIを作成できるので、ちょっとLinuxサーバとの
連携を取りたい時にも利用している。
Nancy
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
PostgreSQLおさらい
? OSSのRDBMS
? 可用性向上のためのMVCCアーキテクチャ
? 組み込み全文検索エンジン
? 豊富な周辺プロダクト
pgpool-II => コネクションプーリング、レプリケーション、負荷分散
Slony-I => レプリケーション
PL/Proxy => 水平分散
FDW => 外部データラッパー
Posgres-XC => 書き込み特化のDBクラスタ
PostgreSQLについて
最初はOracle
創業メンバーにOracle出身者がいたり、たまたま、
創業当時のエンジニアがOracleに習熟していた。
OracleからPostgreSQLへ
規模が大きくなるに従い、コストとインフラの技術的限界が
重荷になっていったため、OSSのDBを検討。
pl/pgsqlの互換性、チューニングの勘所など、
Oracleからの移行コストが低いことがPostgreSQLの
最大の決定要因になった。
なぜPostgreSQLか
クエリ、設計の最適化
極端な高パフォーマンスは必要とされていないので、
基本に忠実に作ることを心がける。
seq scanさせない、頻繁に使うデータは必ずメモリに格納し、
ディスクI/Oを削減する。主要テーブルのCache Hit Rateは
Cactiで常に監視して99%以上を保つ。
これらの実現のために、コードレビューとは別に
SQL/テーブル設計レビューを実施している。
パフォーマンス維持の工夫
データプロバイダはNpgsql
SQL Serverとほぼ同じ記述で利用可能で、OSSとしてはほぼ
唯一の選択肢になる。ADO.NETデータプロバイダとして大抵の
ことはできるが、Entity Frameworkへの対応はない。
品質が特別高い訳ではないことが残念なところ。
? Timeoutが既定値
? 文字列日付の日付型への変換失敗
? 大量のスレッドからの実行時、例外
? 164個のOpen Issue (資料作成時)
ただし、Github上での活動はそれなりに活発で、次期バージョン
ではEntity Frameworkもサポートされるらしい。
C#からのPostgreSQL活用
Npgsqlサンプルコード
using (var conn = new NpgsqlConnection(connStr))
{
conn.Open();
var dataAdapter = new NpgsqlDataAdapter(
@"select * from table_name", conn);
var dataSet = new DataSet();
dataAdapter.Fill(dataSet);
}
他の選択肢は?
有償製品になるが、dotConnectがある。
実はNpgsqlより歴史が長く、Entity Frameworkのサポートや
LINQプロバイダ、Session State Store、Membership
プロバイダなどもサポートしており、Npgsqlと比較して高機能。
? どちらを選ぶか
費用と必要とする機能を天秤に掛けて選択。
弊社では既に分厚くラップしているので今はどちらでも大した
違いはないが、今から作るならdotConnectを選びたい
C#からのPostgreSQL活用
困ることはまずない
今はEntity Frameworkが使えないので初期コストが高くなる
ケースもある。が、運用していく為の周辺環境(ツールや情報)
は充実しているので埋め合わせは十分に可能。
C#だからSQL Server、ではなく、純粋に要件やエンジニアの
保有スキルにあわせてDBを選択すべき。
C#からのPostgreSQL活用
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
Redisおさらい
? Memcachedより少し豪華なインメモリKVS
? データ構造(文字列、リスト、セット、ハッシュ)
? 永続化、レプリケーション
? Redis Cluster
? 将来的にはクラスタリングも可能(度々延期してますが…)
? http://redis.shibu.jp/admin/cluster/
? P2P型で、リバランスも自動
Redis
どこからでも使えるキャッシュ層として
クライアントライブラリにはServiceStack.Redisを利用。
コネクションプーリングやジェネリックインタフェースなどを
組み込みで持ち、気軽に利用可能で便利。
あれ?BookSleeveは?
C#+RedisはBookSleeveでは?
BuildInsider - C#のRedisライブラリ「BookSleeve」の利用法
なんでServiceStack.Redisなの?
Redisの活用 – キャッシュ
複数抽象度から選べるインタフェース
? RedisNativeClient
? RedisClient
? RedisTypedClient<T>
便利な機能が実装済
コネクションプールやハッシング、Pub/SubやLUAスクリプト
の実行も当然サポート。
安定
更新が頻繁で利用者数も多く、安心して利用できる。
ServiceStack.Redisの特徴
? Sample
ServiceStack.Redisの特徴
var client = new RedisNativeClient("127.0.0.1", 6379);
var value = client.LPop("list-key");
var client = new RedisClient("127.0.0.1", 6379);
var value = client.As<Model>().GetItemFromList("list-key");
var manager = new PooledRedisClientManager("127.0.0.1:6379");
var client = manager.GetClient();
var value = client.Get<Model>("key");
いまひとつなインタフェース
RedisClient型が持つpublicメソッドの数 => 437
全てのRedisデータ型を一クラスにまとめているためこんな事に
? client.GetItemFromList()
? client.GetValueFromHash()
Redisデータ型ごとに分けるとか出来そうだが…
メソッド名も初見では少し焦る。
? client.Replace() => keyがあれば更新
? client.Add() => keyがなければ挿入
これらはそれぞれコマンドあるからしょうがないとも言えるが
Push、Pop、Enqueue、Dequeueは絶許。
ServiceStack.Redisの特徴
シンプルなインタフェースと非同期
基本的にはGet/Set。戻り値が特殊でTask<T>で返ってくる。
プリミティブなインタフェースで、byte[]かstringくらいしか
返せないので、そのままアプリケーションに組み込むよりは
ラップしてあげたほうが使いやすい。
詳細は以下を参照
Build Insider - C#のRedisライブラリ「BookSleeve」の利用法
BookSleeveの特徴
どちらを使うべきか?
パフォーマンス重視ならBookSleeve、手軽なコストで使いたい
ならServiceStack.Redis、というのも今は昔。
ラップが面倒なBookSleeveも、今はCloudStructures(※)が
あるのであまり悩むこともなくなった。
※ https://github.com/neuecc/CloudStructures
なぜServiceStack.Redisか?
一番の理由は開発コスト。導入当時はラッパーがなかった。
また、当時はC#4を利用しており、非同期の扱いが手間で、
慣れない非同期を組み込むリスクも踏まえた上での判断。
Npgsqlでの反省も踏まえ更新頻度や実績(利用者数)も参考に。
ServiceStack.Redis or BookSleeve
シリアライズ/デシリアライズ
Google謹製protocol buffersの.NET実装、protobuf-net。
軽量かつ高速、Googleでの利用実績もあって即決。
同類にMessagePack for CLIがあったが、当時は
protobuf-netと比較するとパフォーマンス、実績の点で欠けた
(ただし利便性はMessagePackの方が良かった)
Redisの活用 - キャッシュ
セッションストアとして利用
カスタムセッションストアプロバイダはAL-Redis(※)を利用。
プロバイダはMSDNを見れば誰でも実装できるが全然速度が
出ないので注意(倍違う)。
※ https://github.com/angieslist/AL-Redis
他の選択肢
探せばいくつか出てくるが、排他制御にバグがあって高負荷時
に安定して動いてくれないので、Redisを使うならAL-Redisが
おすすめ。
Redisの活用 - セッション
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
1. Sansanについて
2. Sansanの構成
1. Webフレームワーク
2. DB(PostgreSQL)
3. キャッシュ/セッション(Redis)
4. インフラ
3. まとめ
アジェンダ
たとえば
RDB : Oracle / PostgreSQL / MySQL
NoSQL : Memcached / Redis / MongoDB / RavenDB
Web Framework : Nancy / ServiceStack
DI : Unity / Ninject
テスト: NUnit / NSpec / SpecFlow
ロギング : log4net / NLog
さらに選択肢を増やす
Build Insider - 社内の開発環境の改善&効率化のためにNuGetを活用しよ
う
それぞれが作った、ちょっとしたツールやコードを
社内用NuGetリポジトリに、公開しましょう
.NETでも選択肢の数は変わらない
実績には注意
GitHubならWatchやStar、Issuesなどを確認する。
NuGetならDownloadsなども参考になる。
それらを踏まえて、リスクもきちんと評価した上での採用を。
バグは、ある
テストは十分に。
できればソースコードも読む。利用する箇所だけだったり、
軽く流し読みするだけでも安心感は違う。
ご利用は計画的に
Sansanについて
弊社事例が、皆様の会社での
OSS導入の一助になれば幸いです
? 仲間を募集しています
? http://www.sansan.com/recruit/engineer/
最後に
ご清聴ありがとうございました。

More Related Content

2014 03-15 業務アプリinsider ソフトウェア方面の先進テクノロジー