75
位置情報を使ったサービス「スマ ポ」をPostgreSQLで作ってみた 株式会社スポットライト 浅羽義之

位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

Embed Size (px)

Citation preview

Page 1: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた

株式会社スポットライト 浅羽義之

Page 2: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

はじめに

•この資料はスマポではこうやって運用していますという事例を紹介します。

•他の環境でもそのまま使えるかについてはみなさんのご判断の下、参考にしていただけると幸いですが、何かあっても無保証でお願いします。

Page 3: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

会社紹介

Page 4: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

会社紹介

http://www.smapo.jp/

Page 5: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

スマポ紹介

Page 6: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
Page 7: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
Page 8: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

なぜPostgreSQLか

Page 9: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

PostgreSQL選定理由

•位置情報を扱いたい

•(特に初期段階では)サービス運営のランニングコストを抑えたい

•マニュアルが充実している、等

Page 10: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

POSTGIS

Page 11: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

現在地から 近い順にソート

shop A

shop B

shop C

100m

200m

300m

Page 12: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

http://postgis.net/docs/manual-2.0/ST_Distance.html

Page 13: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

運用編

Page 14: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

サーバ構成

• AWSを利用

• Instance

• m1.large * 2 (master/slave, availability zoneを分けている)

• ELB→App Servers→DB Servers

• EBS

• provisioned IOPS volume (IOPS=1000)

•分析環境は別のデータセンターに配置

Page 15: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

MONITORING

Page 16: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

NEWRELIC

• EnterpriseDBが公開しているnewrelic pluginを利用

• webappのパフォーマンス監視も可能

Page 17: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

VACUUM/ANALYZE

Page 18: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

VACUUM/ANALYZE

• VACUUM/ANALYZEは今のところautovacuum任せ

• UPDATEの多いテーブルはFILLFACTORを設定

• HOT UPDATEと呼ばれる最適化を効かせるため

• http://lets.postgresql.jp/documents/tutorial/hot_1/

Page 19: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

例:FILLFACTOR=90•すごくざっくりした説明です

8KB

8KB

8KB

8KB

PageHeader lineptr1(lp) lp2 lp4lp3 …… lpN

SpecialSpacetuple1tuple2tuple3

tuple4…tupleN

FreeSpace (90%超えたら次のページ)

Page 20: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

REPLICATION

Page 21: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

REPLICATION != BACKUP

• replicationは冗長化・負荷分散が目的

• backupはオペミスした時にも復旧できないといけない

• PITR(Point In Time Recovery)

Page 22: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

STREAMING REPLICATION• PostgreSQL 9.0から導入された機能

• SLAVEはRead-onlyなDBとして動かすことも可能

• hot standby

wal_level = hot_standby max_wal_senders = 5 wal_keep_segments = 16

hot_standby = on max_standby_streaming_delay = 90s

standby_mode = 'on' primary_conninfo = 'host=x.x.x.x port=5432 user=repl_user password=XXXXXXX' restore_command = 'envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-fetch "%f" "%p"'masterの

postgresql.conf

slaveのpostgresql.conf

slaveのrecovery.conf

Page 23: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

archive_mode = on archive_command = 'envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-push %p'

WAL-E• https://github.com/wal-e/wal-e

standby_mode = 'on' restore_command = 'envdir /etc/wal-e.d/env /usr/local/bin/wal-e wal-fetch "%f" "%p"'

postgresql.conf

recovery.conf

Amazon S3

PostgreSQL (master)

PostgreSQL (slave)

PostgreSQL (analytics)

backup-push

backup-fetchwal-push

wal-fetch

Page 24: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

REPLICATION監視

• select * from pg_stat_replication;

• replicationが正常に動いていればslaveの数だけ結果が帰ってくる

• masterで実行

Page 25: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

ANALYTICS

Page 26: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

ANALYTICS DB

• fluentdでログデータを回収し、分析専用のPostgreSQLへ格納

•各種KPIをPostgreSQLで集計

•マシンパワーが必要なので、物理サーバで構築

Page 27: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

WARMUP

Page 28: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

データをキャッシュに載せる• cache?

• PostgreSQLのshared_buffer

• OSのページキャッシュ(free -mで確認)

•他にもあるが省略

•サーバ再起動時などはキャッシュがクリアされている

Page 29: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

載せ方• shared_buffer

• SELECT count(*) FROM sample_table

•インデックスは載らないので注意

• page cache

• (ionice -c 3) cat 物理ファイル > /dev/null

Page 30: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

ファイルの場所test=# SELECT relname, current_setting('data_directory') || '/' || pg_relation_filepath(oid) as filepath, pg_relation_size(oid) as filesize FROM pg_class WHERE relname = 'sample_table'; ! relname | filepath | filesize --------------+-----------------------------------------------+---------- sample_table | /var/lib/postgresql/9.2/test/base/16385/18572 | 1351680 (1 row)

test=# SELECT relname, current_setting('data_directory') || '/' || pg_relation_filepath(oid) as filepath, pg_relation_size(oid) as filesize FROM pg_class WHERE oid IN (SELECT indexrelid FROM pg_index WHERE indrelid = (SELECT oid FROM pg_class WHERE relname = ‘sample_table')); ! relname | filepath | filesize --------------------+-----------------------------------------------+---------- sample_table_pkey | /var/lib/postgresql/9.2/test/base/16385/22203 | 16384 idx_sample_table_b | /var/lib/postgresql/9.2/test/base/16385/22205 | 16384 idx_sample_table_c | /var/lib/postgresql/9.2/test/base/16385/22206 | 16384

Page 31: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

運用トラブル集

Page 32: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

#1 SLOW QUERY

Page 33: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

何を見ようか?

• newrelicのレスポンスタイム

• slow query log

• log_min_duration_statement = 1s

• newrelic/cloudwatchのサーバステータス

Page 34: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

参照のチューニング• EXPLAIN ANALYZEでどの実行プランが遅いか確認

• table scanが遅い

• indexが無い or indexが不適切?

• table joinが遅い

• ANALYZEが足りないか確認

• limit句がある場合はsubqueryにしてJOINの回数を減らせるか試す

Page 35: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

EXPLAIN ANALYZE•実行計画がそれぞれどれくらい時間かかったか見ることが可能

test=# EXPLAIN ANALYZE SELECT t1.a, t2.a FROM t1, t2 WHERE t1.a = t2.a and t1.a < 100; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- Nested Loop (cost=0.85..805.31 rows=95 width=8) (actual time=0.038..3.319 rows=99 loops=1) -> Index Only Scan using t1_pkey on t1 (cost=0.42..10.09 rows=95 width=4) (actual time=0.012..0.449 rows=99 loops=1) Index Cond: (a < 100) Heap Fetches: 99 -> Index Only Scan using idx_t2_a on t2 (cost=0.42..8.36 rows=1 width=4) (actual time=0.006..0.011 rows=1 loops=99) Index Cond: (a = t1.a) Heap Fetches: 99 Total runtime: 3.782 ms (8 rows)

プランノード コスト 実行時間

Page 36: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

やったこと•使ってほしいインデックスが使われていないのでクエリを書き換え

•インデックスないものは追加

• JOINしたあとにLIMITしていた箇所は、先にLIMITしてからJOINするように変更SELECT *FROM a, b WHERE a.id = b.id and a.hoge >= 1000 LIMIT10;

↓ SELECT* FROM (SELECT * FROM a WHERE a.hoge >= 1000 LIMIT10) as aa,

b WHERE aa.id = b.id

Page 37: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

#2 MAJOR VERSION UP

Page 38: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

PostgreSQL 9.1→9.2 PostGIS 1.5→2.0

tool down time comment

pg_upgrade △postgisのupgradeに対応していない?

pg_dump/pg_restore ☓ 停止時間が長い

slony-I ◯ 面倒

Page 39: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

MASTER切り替え

PostgreSQL (旧master)

PostgreSQL (旧slave)

PostgreSQL (新master)

PostgreSQL (新slave)

AppServer

slonyのreplication

streaming replication

Page 40: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

MASTER切り替え

PostgreSQL (旧master)

PostgreSQL (旧slave)

PostgreSQL (新master)

PostgreSQL (新slave)

AppServer

slonyのreplication 停止

streaming replication

Page 41: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

検証環境で実験

Page 42: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

問題なし!

Page 43: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

切り替え当日

Page 44: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

SIGSEGV!!!

Page 45: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

結局pg_dump/pg_restoreやりました。すみません。

9.2→9.3でリベンジ予定。

Page 46: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

#3 LOCK待ち問題

Page 47: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

SELECT WAITING

• DB migration時などにロック待ちが発生

• psコマンド

• ps aux | grep postgres | grep waiting

• SELECT * FROM pg_locks;

•もう少し細かくロックの獲得状況を確認できる

Page 48: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

クエリキャンセル

•クエリをキャンセル

• SELECT pg_cancel_backend(pid);

• or kill -INT pid

•クエリをキャンセルしてバックエンドプロセスを落とす

• SELECT pg_terminate_backend(pid)

• or kill -TERM pid

Page 49: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

#4 DEADLOCK

Page 50: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

ERROR: deadlock detected

Page 51: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

デッドロックの原因

•ロックを取る順番が異なるため

•テーブルロック、行ロックなど

•ロック獲得

•明示的なロック

•暗黙的なロック

Page 52: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

実際に起きたケース(簡略版)2013-10-30 00:11:22 JST DETAIL: Process 3225 waits for ShareLock on transaction 11759339; blocked by process 3040. Process 3040 waits for ShareLock on transaction 11759337; blocked by process 3225. Process 3225: insert into foo (x,y,z) select x, 12345, z from bar where id in (( values (1), (2), (3) ) except ( select x from foo where date = '...')) ! Process 3040: insert into foo (x,y,z) select x, 12345, z from bar where id in (( values (2), (3), (1) ) except( select x from foo where date = '...')) !

Page 53: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

調査

•前提:開発環境でやること

• postgresql.conf

• log_statement = all

• log_line_prefixに%pをつける

• COMMIT直前のpg_locksを確認

Page 54: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

一次調査でわかったこと

•テーブルロックの順番は同じ

•そもそも強いロックレベルでテーブルロック取ってない

• INSERTなのでfooに対する行ロックはあるのか?

•要はよくわからなかった

•ただ、確かにinsertで片方が待たされる

Page 55: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

止まっている箇所を調べる

• PostgreSQLをデバッグビルド

• CFLAGS=-O0 ./configure —prefix=$HOME —enable-debug

•片方でSELECT pg_backend_pid()

• gdb -p backendのpid

Page 56: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

BACK TRACE(gdb) bt … #5 0x00000000006f0ada in LockAcquire (locktag=0x7fff7ce28d20, lockmode=5, sessionLock=0 '\000', dontWait=0 '\000') at lock.c:662 #6 0x00000000006effec in XactLockTableWait (xid=768) at lmgr.c:495 #7 0x00000000004890e4 in _bt_doinsert (rel=0x7fa0c1634838, itup=0x2122468, checkUnique=UNIQUE_CHECK_YES, heapRel=0x7fa0c162f820) at nbtinsert.c:168 #8 0x000000000048f3b4 in btinsert (fcinfo=0x7fff7ce28e40) at nbtree.c:257 #9 0x0000000000819bb5 in FunctionCall6Coll (flinfo=0x2115650, collation=0, arg1=140328416004152, arg2=140735288611488, arg3=140735288611840, arg4=34743148, arg5=140328415983648, arg6=1) at fmgr.c:1439 #10 0x0000000000487c64 in index_insert (indexRelation=0x7fa0c1634838, values=0x7fff7ce292a0, isnull=0x7fff7ce29400 "", heap_t_ctid=0x212236c, heapRelation=0x7fa0c162f820, checkUnique=UNIQUE_CHECK_YES) at indexam.c:216 #11 0x00000000005f29aa in ExecInsertIndexTuples (slot=0x21167c0, tupleid=0x212236c, estate=0x2115e60) at execUtils.c:1087 #12 0x0000000000605273 in ExecInsert (slot=0x21167c0, planSlot=0x21167c0, estate=0x2115e60, canSetTag=1 '\001') at nodeModifyTable.c:248

Page 57: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
Page 58: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

create table tt(a text unique); select pg_backend_pid(); begin; insert into tt values (‘aa’), (‘bb’)

select pg_backend_pid(); begin; insert into tt values (‘bb’), (‘aa’)

(gdb) b _bt_doinsert Breakpoint 1 at 0x488fc7: file nbtinsert.c, line 106. (gdb) c Continuing. !Breakpoint 1, _bt_doinsert (….) at nbtinsert.c:106 (gdb) c Continuing. !Breakpoint 1, _bt_doinsert (….) at nbtinsert.c:106 ‘aa’をinsertしたところで止める !(gdb) c

(gdb) b _bt_doinsert Breakpoint 1 at 0x488fc7: file nbtinsert.c, line 106. (gdb) c Continuing. !Breakpoint 1, _bt_doinsert (….) at nbtinsert.c:106 (gdb) c Continuing. !Breakpoint 1, _bt_doinsert (….) at nbtinsert.c:106 ‘bb’をinsertしたところで止める !(gdb) c

psql psql

gdb gdb

Page 59: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

回避方法2013-10-30 00:11:22 JST DETAIL: Process 3225 waits for ShareLock on transaction 11759339; blocked by process 3040. Process 3040 waits for ShareLock on transaction 11759337; blocked by process 3225. Process 3225: insert into foo (x,y,z) select x, 12345, z from bar where x in (( values (1), (2), (3) ) except ( select x from foo where date = ‘…’)) ORDER BY x ! Process 3040: insert into foo (x,y,z) select x, 12345, z from bar where x in (( values (2), (3), (1) ) except( select x from foo where date = ‘...')) ORDER BY x !

Page 60: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

#5 TV放映

Page 61: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

9/9 19:00-21:00 NTV

有吉ゼミ

Page 62: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

AWS

• instanceをscale up

• m1.large → m3.2xlarge

• app server増強

• Elastic LoadBalancerのpre-warming

Page 63: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

PERFORMANCE TEST

• pgbenchを使用

• tps(transaction per second)を知ることができる

• -f 実行したいSQLファイル

• -c 並列数

• -t トランザクション数

• New Relic/CloudWatchでパフォーマンスを監視

Page 64: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

当日

• warmupを直前で実施

• master/slave

•あとは祈るのみ

Page 65: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

振り返り

• 3000over req/sec

• app serverが持ちこたえられない時間帯(数分)が発生

•ゴールデン放送のアクセスはすげー

• DBについては、checkpointのチューニングが甘く、disk書き込みが結構発生した

Page 66: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

#6 TV放映(再放送)

Page 67: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

10/614:00-16:00 NTV

有吉ゼミ(再)

Page 68: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

再放送をたまたま気がついたのが2日前

(教えてよ。。。)

Page 69: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

postgresql.conf• memory

• shared_buffer=搭載メモリの1/4程度

• wal_buffer=16MB

• checkpoint

• checkpoint_segments = 64

• checkpoint_timeout = 1h

• checkpoint_completion_target = 0.9

!

• planner

• effective_cache_size=page cacheのサイズ

• random_page_cost=2.0

• lock

• deadlock_timeout = 10s

Page 70: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

振り返り

•問題なく捌けた

•再放送は連絡こないので要注意

4000%?

Page 71: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

まとめ

Page 72: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

PostgreSQL使ってみて

•スタートアップのサービスで使うRDBMSとしてよい

•機能面、コスト面

•もちろんMySQLもすごいと思います

•運用も工夫次第で色々できる

•一台で結構なリクエスト数を耐えられる!

Page 73: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

宣伝

Page 74: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

エンジニア絶賛募集中! (特にインフラやりたい人)

http://www.smapo.jp/recruit/index.html

Page 75: 位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo

おわり