unless’s blog

日々のちょっとした技術的なことの羅列

PostgreSQLのロジカルレプリケーションとストリーミングレプリケーションの違い

これはなに?

ちょっとStreaming ReplicationとLogical Replicationの違いを調べる機会があったのでまとめてみた

レプリケーションの種類の比較

PostgreSQLでは、バージョン9.0よりストリーミングレプリケーション(Streaming Replication)機能を利用することができるようになり、バージョン10からはロジカルレプリケーションが利用可能になったので、2つの種類のレプリケーション機能が利用できる
結論の表だけ先に書くと、下記になる

Streaming Replication Logical Replication
伝播するもの WAL WALの情報を論理的なレベルに変換(デコード)したもの
レプリケーション範囲 全てのデータベース(データベースクラスタ単位) データベース単位、テーブル単位で設定可能
異なるMajorVersionのサポート 不可
異なるOSのサポート 不可
スタンバイ側での更新 不可

備考

正確にはLogical ReplicationとStreaming Replicationはちょっと概念上の階層がずれている気もする
Streaming Replicationについては高可用性を担保するためのLog Shippingの設定の一つ
本来はWALレコードを一度に1ファイル(WALセグメント)ずつ転送するファイルベースのログシッピング方式でWALファイル(16MB)がいっぱいになるとファイル単位で転送されるが、Streaming ReplicationについてはWALレコードが生成されたらストリーミングする設定のこと
WALがなにかはこの辺に書いてある
上記を見ればわかる通り、 これはPhysical Replicationと言っていい
Logical Replicationはその名の通り論理レプリケーションなので、対比構造ならPhysical Replicationと対比になると思われる
しかし、わかりやすさを優先してこのような対比構造で書いている

Streaming Replicationの仕組み

Primaryがクラッシュリカバリーやロールバックのために保存しているWALをStandbyに転送して、Standby側がそれを適用することで実現している
Streaming ReplicationについてはこのWALレコードをリアルタイムにStandbyに転送することで実現している
転送はPrimary側の wal sender プロセスと、Standby側の wal receiver プロセスで行っている

streaming

Logical Replicationの仕組み

Primary側でpublication、Standby側にsubscriptionを定義し、情報を伝播させる
publicationはテーブルやテーブルグループから生成された更新セットで、INSERT、UPDATE、DELETE、TRUNCATEのうちのどのような組み合わせにも制限することができる
subscriber(subscriptionの定義をしたサーバ)のDatabaseは、publicationを定義することで他のDatabaseに対するPublisher(publicationの設定をしたサーバ)としても使用できる
各々のsubscriptionは、一つのレプリケーションスロット(ここを参照)を通じて更新が通知される

logical

Logical Replicationはsubscriberでもデータ更新ができるので、到着したデータが制約違反をするとレプリケーションが止まるので注意が必要
俗にいうConflictと言われるもの

それぞれのレプリケーションの制約

Streaming Replication

Logical Replication

それぞれの使い時

Streaming Replication

  • 参照処理の負荷分散
  • バックアップ
  • 高可用性構成

Logical Replication

最後に

同期レプリケーション周りもちょっと書こうかと思ったけど、それはそれで長くなるし、文脈がちょっと違うので省略した

Go 1.19 でruntime/pprofのgoroutine profileにおいてSTWの時間が大幅に軽減されたらしいので調べてみた

これはなに?

Go 1.19のRelease Notesを眺めていたら、runtime/pprof でgoroutine profileを取得する際のSTW(Stop-the-world)の一時停止時間が大幅に短縮され、アプリケーションに対する全体的なレイテンシーの影響が軽減されたという記述を見つけました

runtime/pprof
Stop-the-world pause times have been significantly reduced when collecting goroutine profiles, reducing the overall latency impact to the application.

tip.golang.org

個人的にどのような変更でSTWの時間が軽減されたのか気になったので追ってみました

変更を探す

1.19に入ったどの修正が対象なのかを探すために、Githubから runtime/pprof 配下の変更履歴を見てみたけど、対象っぽいものを見つけられませんでした

github.com

しかし、Release Notesに significantly reduced って記載するくらいなので、絶対に速度検証もしてるはずで、別の場所の変更で大幅に改善したのかと思い、 runtime 側を探してたらそれっぽいcommitを見つけられました

github.com

commitはこちら

github.com

Gerrit上だとこちら

https://go-review.googlesource.com/c/go/+/387415

関係するProposal

そもそものissueはこちら

github.com

大量のgoroutineを扱うアプリケーションだとgoroutine profileのレイテンシーが厳しいよって感じです
goroutineの量に比例してgoroutine profileの時間が伸びてるよって話

関係するProposalはこちら

github.com

内容としては SetMaxDumpGoroutine を追加して、dumpするgoroutineの数に制限をつけちゃえって感じです
PRも出されてます

github.com

でもこのProposalはdeclineされた模様
理由としては CL387415 で様子を見て、それでもだめならその時に考えよう
we should hold off on adding any new API right now, which we would be stuck with forever. って感じのようです

変更内容

そもそもgoroutine profileは、アプリ内のすべてのgoroutineの一貫したスナップショットを取得するためにSTWする必要があります
アプリ内の全ゴルーチンのスナップショットを取得する必要があり、allgs の反復中にSTWしたままにすると、アプリ内のgoroutineの数に比例して一時停止することになります

この変更ではその代わりに、STWしてる間に一定量のbookkeepingだけ行うようにしています
バリアを導入して、goroutineの実行を許可する前に、goroutineがprofileに表示されることをスケジューラーが確認し、そのスタックがSTW中とまったく同じように記録されるようにします
アプリが通常の操作を再開している間、allgs を反復処理し、その間にスケジュールされていない限り (自分自身をプロファイリングしていない限り)、それぞれをprofileに追加します
最後にもう一度STWしてバリアを取り除き、一定量のクリーンアップ作業を行います

これによる影響で、GoroutineProfile の固定オーバーヘッドとゴルーチンごとの CPU 時間コストの両方が増加してます
また、スケジューラーが他のゴルーチンを実行するために呼び出しを中断する可能性があるため、GoroutineProfile への呼び出しのwall-clock latencyも増加してます

この辺はトレードオフなので仕方ないところかなと

コードの変更点

Goroutine scheduler

コードの変更点を見ていく前にそもそもGoroutine schedulerの動きとか変数とかを把握していないと読みにくいので、最初にこの辺を読んでおくとスムーズかと思います

github.com

とりあえずこれが頭に入っていると、雰囲気は掴めるとは思います

// The main concepts are:
// G - goroutine.
// M - worker thread, or machine.
// P - processor, a resource that is required to execute Go code.
//     M must have an associated P to execute Go code, however it can be
//     blocked or in a syscall w/o an associated P.

Design Docのリンクも置いておきます

docs.google.com

いままで

いままではシンプルに世界を止めて、すべてのg分(allgs)を反復処理して、世界を再開させていた模様

github.com

変更点

gにstatus管理するためのフィールドが追加されました

github.com

github.com

StatusはgoroutineProfileState で(Absent,InProgress,Satisfied)があります

github.com

profileの状態管理用の変数も新たに切られていて

var goroutineProfile = struct {
    sema    uint32
    active  bool
    offset  atomic.Int64
    records []StackRecord
    labels  []unsafe.Pointer
}

github.com

STWして状態を書き込むようにしてます

github.com

その後、世界を再開させてから、profileされるべきgoroutineか確認して

github.com

goroutine profileに書き込むようになってます

github.com

オーバーヘッドの原因はこの辺でチェック処理が入ったことによる影響だと思われます

github.com

github.com

最後にクリーンアップ処理をSTWして行ってます

github.com

まとめ

ちょっと気になってたので、どのようにpprofのgoroutine profileのSTWの時間を削減したのか調べてみました
簡単にまとめると
STWしてgoroutineの数だけ反復処理をしてprofileを取得していた処理を
STWしてgoroutineの数だけbookkeepingだけ行い
世界を再開してからbookkeepingされた情報を元にgoroutine profileの書き込みを行うようにした
その影響でgoroutine profileの固定オーバーヘッドとCPU時間コストが少し増えた
って感じだと思われます

goroutineの数が多いアプリケーションを作ってる人にはうれしい修正だったのではないかと思いました 今後はgoroutineの数が多いアプリケーションを作っている人も安心してprofilingができるので、ぜひとも取得することをおすすめします

逆に、あまりgoroutineの数が多くないアプリケーションの場合はオーバーヘッドが増えただけかもしれません とはいえ、問題になるようなオーバーヘッドではないと思われるのでprofileはどんどん取得して問題はないかなと思います

それではみなさん、ハッピーはProfiling Lifeを!

PostgreSQLでIndex名,column名,型名の一覧を取得するSQL

これはなに?

タイトルのままだけど、PostgreSQLでIndex名とcolumn名と型名の一覧が欲しかった しかし意外と取得に苦労したのでSQLを貼っておく

SQL

最初は Information_schema でうまいこと引いてこれないかなって思って試したけど意外とできなかった
理由としては Information_schema にcolumnとindexを紐付けるテーブルが存在しなかったこと Information_schema.colums でcolumnの情報は取れて、 pg_indexes でindexの情報は取れたけど紐付けは難しかった
pg_indexes のcreate文をparseすればいけるのかもしれないが、ちょっとだるいのでサクッとSQLだけで取りたかった

それと型の情報を出すのも意外にしんどい
PKだけであれば information_schema. table_constraints から引けば良さそうであったが、PK意外のindexが取れなそうであった

上記を踏まえて、システムカタログから取ってくるようにしてみた

www.postgresql.jp

SELECT
     t.relname AS table_name
    ,i.relname AS index_name
    ,array_to_string( array_agg( a.attname ), ',') AS column_names
    ,array_to_string( array_agg( tp.typname ), ',') AS column_types
FROM
     pg_class AS t
    ,pg_class AS i
    ,pg_index AS ix
    ,pg_attribute AS a
    ,pg_tables AS ta
    ,pg_type as tp
WHERE
        t.oid = ix.indrelid
    AND i.oid = ix.indexrelid
    AND ix.indisprimary = false
    AND ix.indisunique = false
    AND a.attrelid = t.oid
    AND a.attnum = ANY( ix.indkey )
    AND t.relkind = 'r'
    AND t.relname = ta.tablename
    AND ta.schemaname = current_schema()
    AND a.atttypid = tp.oid
GROUP BY
     t.relname
    ,i.relname
    ,ix.indisprimary
    ,ix.indisunique
ORDER BY
     t.relname
    ,i.relname;

複雑なSQLになってしまったが、取れたので良かろう

もっときれいに取れる方法知ってる人は教えてくだされ

関連Link

負荷試験を定期的に実施できるように体系化した話

これはなに?

Kyash Advent Calendar 2021 22日目の記事です

昨年のAdvent Calendarでは負荷試験環境を作った話を書きました
今回は負荷試験の実施方法を体系化し、定期的に実施できる状態を作ることができてきたので、その話をまとめていきたいと思います

おまえだれ?

Kyashで主にお金の入出金周りを担当しているチームでBackend Engineerをしている @uncle__ko です
銀行やコンビニなどとシステム接続を行ったり、各種電文のParserを作ったり、電文の暗号化/復号化をしたり、マイクロサービス間&外部システムとの結果整合性の担保に苦心したりしています

事前準備

負荷試験をただ闇雲に行っていても意味がありません
何事もゴールを定めるのがとても重要ですし、負荷試験においても例外ではないと思ってます
ですので、Backend Engineer,SRE,PdM等の関係者を集めて全員の認識を揃えることが重要です

目的を設定せよ

今回の負荷試験の結果で何を得たいのかを決めます
それによってアプローチも変わってきますので、まずは全員で目的を定めていきます

    • 想定されるピーク時のRequestを受けても問題なく稼働することが知りたい
    • 現状のシステムで捌ける限界値を知りたい
    • Push通知のrate limitを決めたい

観点を決めよ

負荷試験を実施するにあたりどのような観点でテストをするのかを決めます
目的によって色々な観点がでるかと思います
どのようなアプローチで負荷テストして、どのような値を注視していくのかを決めることで、負荷試験結果を振り返りやすくします

    • 瞬間的なピーク値のテスト
    • 広告/キャンペーン/push通知など瞬間的に負荷が増大するテスト
    • 長時間の平均値のテスト
    • 通常稼働時のテスト
    • 負荷を大きくしていくテスト
    • 限界を知るためのテスト

対象を定めよ

何処にどの程度の負荷を掛けるべきかを決めます
目的に応じて必然的に決まるかと思います

負荷を試算せよ

  • ピーク値
  • 平均値

を決めます
ここに関しては負荷試験の目的ベースにエンジニアだけではなくPdMやドメインに詳しい人と一緒に、実際のユーザ数等を含め現実に使い数値を算出します
ちなみに負荷試験でここが一番難しいと感じます
定石も正解もない部分だと思ってます

ただ、あまり現実的じゃない数値でテストしたところで、サーバがオーバースペックになってしまったり、逆に想定より多くてシステムが耐えれなかったりしたら意味がないので、とても重要な部分です

    • 大規模なキャンペーンでPush通知を全ユーザに打つので耐えられるかを試験する
      • 送信ユーザ数と開封率を考慮して、想定されるアクセス数を試算
      • Push通知の遷移先で叩かれうるAPIを調査
      • これらの情報をもとに目標負荷を設定する

確認方法を決めよ

どの項目をどのように確認するかを決めます
チェック項目と確認方法を事前に決めておくことで、振り返りをしやすくします

    • datadogでRDSの aws.rds.cpuutilization を見る
    • Amazon CloudWatchでRDSの aws.rds.cpuutilization を見る

ちなみにKyashではDatadogを使ってシステムのmonitoringをしているので、負荷試験用のdashboardを作っています

dd_dashboard

シナリオを作成せよ

やっとシナリオが作成できます
Kyashの場合は昨年の記事にあるようにlocustを使っているので、locustのシナリオファイルとして、ここまで決めてきたものを取り入れたコードを記述していきます
記述の方法や構成等は昨年の記事をご覧ください

Locust + AWS ECS(Fargate)で負荷試験環境を作った話 - unless’s blog

実施

https://1.bp.blogspot.com/-6pDrDpYKUCg/Xor0RTjWgtI/AAAAAAABYL0/-y57hak6vKEhfrtHwOashooPxNMUaYJ8ACNcBGAsYHQ/s400/online_kaigi_man.png

実施については、負荷試験担当の人以外にも興味がある人は参加できるように事前にSlack等で声がけしたりしてます
また、負荷試験用の専用Channelを用意していて、負荷試験に関することはそのChannelに情報が集約されてます
そして、負荷試験当日はみんなでわいわいしながら負荷試験を実施してます
上で紹介したdashboardを見ながらネックになっている処理や、マイクロサービスを特定しながらみんなで意見交換しつつ負荷を掛けていきます

結果の共有

負荷試験の結果を振り返るMTGを実施します
目標を達成していない場合はどこを直すべきか、それはすぐに可能か別の方法はあるか等をメンバーで考えます
また、その結果を受けて何をいつまでに実施しないといけないのか、次回の負荷試験の日程はいつなのかなどを決めるようにしています
このように、実施と振り返りを目標が達成できるまで繰り返していきます

Kyashでは実施結果をGitHub issueで管理していて、議事録としてその時の結果やメンバー、振り返り内容とネクストアクションを残しておき、後世に知見を残せるようにしています 結果に関してはスクリーンショットも残すようにしています

issue

next_action

まとめ

このようにKyashでは闇雲に負荷試験を実施するわけではなく、目的、観点、対象を把握した上で目標を設定し、その目標をクリアするために負荷試験を行なっています
この実施方法が正解とも思っていませんし、まだまだ改善の余地はあるかもしれませんが、ある程度はこの方法で回るようになってきたかなと思っております
負荷試験などはどうしても後回しにされがちで、特にベンチャー企業などではなかなか実施できないことも多いと思います
Kyashでも大きめのプロジェクトのタイミングなどでは実施できていましたが、定期的に実施することは出来ていませんでした
しかし、このようにある程度体系だった方法を確立し提案資料にまとめてEMやPdMに提案していったところ四半期に1回実施できるような体制が作れるようになりました
今後も実施方法をブラッシュアップしつつ、しっかり負荷対応も行っていき、品質の高い、ユーザが安心して使用できるアプリを作っていきたいと思います

さいごに

Kyashでは一緒に負荷試験を実施してくれる仲間を募集しています
すこしでも興味を惹かれましたらぜひ応募してください!

サーバーサイドエンジニア / Serverside Engineer - 株式会社Kyash

また、下記もぜひチェックしてみてください!

Kyash Advent Calendar 2021はまだ続きます!明日の投稿もお楽しみに!

Datadog Profilerで継続的なProfilingを実施できるようにした話

おまえだれ?

株式会社Kyash でサーバサイドエンジニアをしている @uncke__ko です
Fundsチームに所属していて主にお金の入出金部分を担当しています

これは何?

Kyashではシステムの監視やモニタリングにDatadogを使用しています

www.datadoghq.com

Datadogにある Continuous Profilerという機能を使い、継続的にProfilingできる環境を整えたのでその話になります

docs.datadoghq.com

Profilerとは

プロファイラとはアプリケーションの性能を解析するためのツールです
ソフトウェア開発をしていると下記のようなことが度々起こった経験が1度はあると思います

  • OOMが発動するようになる
  • latencyが遅くなる
  • アプリケーションの動作が徐々に重くなる

Profilerがあると、このようなときにアプリケーションのCPU使用率やメモリ使用率、関数のCall数など様々な情報が手に入るので調査が行いやすくなり原因を特定できるようになることが多いです

いままでのKyash

KyashのサーバサイドではGolangを使用しています
Golangにはpprofというツールが用意されているので、Kyashでもこれを使用して問題が起こったときにProfileを取得していました Call GraphやFlame Graphなどもあり見やすいです

CallGraph https://github.com/google/pprof/blob/master/doc/images/callgraph.png

https://github.com/google/pprof/blob/master/doc/images/callgraph.png?raw=true

なぜDatadog Profilerに移行したか

Profilingするだけであればpprofでも問題はありませんでした
しかし、pprofの特性上、webサーバに対してProfileを取得する場合はhttpRequestを行わなければなりません
どこからhttpRequestを行うのか、portはどこに当てるのか、ECS Fargateにインフラを移行中なのでServiceによってProfileの取得方法に差異がでてしまったりしました
また、profilerを導入してる企業だとあるあるかと思いますが、問題が起こったときにしかProfilerを見ずに、継続的にProfilingを実施して改善するActionにつなげにくいという問題もあります
そこでKyashで使っているDatadogにProfiler機能が追加されたので移行することにしました
メリットとしては下記かと思います

  • 見るべきツールが統一されるのでDatadogだけを気にしていればいい
  • Serviceのインフラにより取得方法が変わることがない
  • 簡単にGUIで結果が見れる
  • 定期的にProfilingしてくれるので障害時の情報もサクッと見れる
  • 定期的にProfilingしてくれるのでEngineerの参入障壁が低く継続的にProfileベースでコードを改善していけるポテンシャルがある

GolangでProfilerを有効にする

すでにDatadogを導入しているならかなり簡単です

  1. agentのverを 7.20.2以上 or 6.20.2以上にする

  2. packageをinstallする

go get gopkg.in/DataDog/dd-trace-go.v1/profiler
  1. profilerをimportする
import "gopkg.in/DataDog/dd-trace-go.v1/profiler"
  1. profilerを開始する
err := profiler.Start(
    profiler.WithService("<SERVICE_NAME>"),
    profiler.WithEnv("<ENVIRONMENT>"),
    profiler.WithVersion("<APPLICATION_VERSION>"),
    profiler.WithTags("<KEY1>:<VALUE1>,<KEY2>:<VALUE2>"),
    profiler.WithProfileTypes(
      profiler.CPUProfile,
      profiler.HeapProfile,
      // The profiles below are disabled by default to keep overhead
      // low, but can be enabled as needed.

      // profiler.BlockProfile,
      // profiler.MutexProfile,
      // profiler.GoroutineProfile,
    ),
)
if err != nil {
    log.Fatal(err)
}
defer profiler.Stop()

導入方法なども公式にDocmentにしっかり記載されてるので迷うことはないと思います

docs.datadoghq.com

GolangのProfilerで取得できる項目

GolangのDatadog Profilerは裏でpprofが使用されています

github.com

ですので基本的にpprofで取得できる内容とほぼ同じですが下記が取得できる内容です(documentからの引用です)

CPU Time

各関数がCPUでの実行に費やした時間を示します。ネットワーキング、チャンネル、ミューテックス、スリープの待機のような Off-CPU の時間は、このプロファイルでキャプチャされません。ミューテックスおよびブロックのプロファイルをご確認ください。

Allocations

アプリケーションの開始以降、各関数によってヒープメモリに割り当てられたオブジェクトの数を示します。これには、後で解放された割り当ても含まれます。これは、ガベージコレクションの負荷を調査する際に役立ちます。

Allocated Memory

アプリケーションの開始以降、各関数によって割り当てられたヒープメモリの量を示します。これには、後で解放された割り当ても含まれます。 Go ではこれを alloc_space と呼びます。これは、ガベージコレクションの負荷を調査する際に役立ちます。

Heap Live Objects

各関数によってヒープメモリに割り当てられたオブジェクトの数と、アプリケーションの開始以降に割り当てられたまま残り、最後のガベージコレクション以降存在するオブジェクトの数を示します。これは、サービスの全体的なメモリ使用量を調査する際に役立ちます。

Heap Live Size

各関数によって割り当てられ、アプリケーションの開始以降に割り当てられたまま残り、最後のガベージコレクション以降存在するヒープメモリの量を示します。Go ではこれを inuse_space と呼びます。これは、サービスの全体的なメモリ使用量を調査する際に役立ちます。

Mutex

アプリケーションの開始以降、関数がミューテックスを待機している時間を示します。このプロファイルのスタックトレースは、ミューテックスで続行をブロックされた別の goroutine を許可した Unlock() 演算子をポイントします。スピンロックを使用したショートミューテックスの競合はこのプロファイルでキャプチャされませんが、CPU プロファイルで確認できます。

Block

アプリケーションの開始以降、関数がミューテックスおよびチャンネルオペレーションを待機している時間を示します。スリープ、GC、ネットワーク、Syscall オペレーションは、このプロファイルでキャプチャされません。ブロッキングオペレーションは、ブロックが解除されてからのみキャプチャされるため、スタックしていると思われるアプリケーションのデバッグにこのプロファイルを使用することはできません。ミューテックスの競合の場合、このプロファイルのスタックトレースはブロックされた Lock() 演算子をポイントします。これにより、ブロックされているプログラムがわかり、ミューテックスプロファイルにより、競合の原因となっているプログラムの部分がわかります。この点に関する詳しい情報は、Go におけるプロファイリングのブロックリサーチをご覧ください。

Goroutines

同じ関数(CPU 上および待機中の Off-CPU)で現在実行中の goroutines の数のスナップショットを示します。スナップショット間での goroutines の増加は、プログラムで goroutines がリークしていることを示しています。最も健康なアプリケーションでは、このプロファイルはワーカープールにより使用され、その goroutines 使用数が表示されます。遅延の影響を非常に受けやすく、大量の goroutines(10.000 以上)を使用するアプリケーションの場合、このプロファイルを有効にすると O(N) stop-the-world 型の一時停止が必要になることにご留意ください。一時停止はプロファイリング期間(デフォルトは 60 秒)ごとに発生し、通常 goroutine あたり ~1µsec 継続します。~100ms の p99 レイテンシー SLO の典型的なアプリケーションでは、この警告を無視することが可能です。より詳しい情報については、Go における Goroutine プロファイリングリサーチをご覧ください。

docs.datadoghq.com

実際にProfilingしてみる

APM->Profile Search でprofilerを確認します

CPU Timeはこのような感じ
frame grapthも出て見やすいです call数が出てくれないのが少し不便なところなので、今後のupdateに期待です

HeapLiveSizeはこんな感じです こちらもかなり見やすくgrapth化してくれています

個人的にGolangでDatadog Profilerを使う上で便利だと感じているのはGoroutineの項目です
Goroutineのリークなどの調査に役立っていてとても助かっています
とはいえ、Goroutinesの項目でも触れてますがSTWが発生するので高頻度でのGoroutinesの取得は慎重になったほうがよいかもしれません
リーク周りでおもしろい記事を弊社メンバーが書いてるので興味があればこちらもぜひご覧ください

ECSへ移行したらマシンリソースを使い果たした問題がnet/httpのhttp.Transportの使い方の誤りにあった話 - Qiita

移行してみてどうだったか

まだすべてのマイクロサービスの移行が完了したわけではありませんが、主要なマイクロサービスには導入できてきました
実際に導入してみて、logやdashboardを見るついでにprofilerが気軽に見れる状態なので、profilerを見ることへの抵抗は減ったのかなと思います
また、障害時にもProfilerのおかげで調査の足がかりになったこともあり、改めてProfilerを見ることの大切さに気が付きました
とはいえ、まだまだ継続的にProfilerをみて改善する環境には程遠いと思ってますので、この辺は徐々に改善していきたいなと思っています

おわりに

最近、Kyashに導入したDatadogProfilerの話を書いてみました DatadogはかなりDocumentが充実しているので導入に詰まるようなことはないと思います 継続的なProfilingを気軽にできる点はとても素晴らしいと思いますので、Datadogを使用していて、まだProfilerを導入していない企業の方はぜひ導入を検討してみてください

また、Kyashでは一緒に働くエンジニアの皆様を募集しております
もしご興味ありましたら、以下のリンクをご覧ください

Kyash募集職種一覧
カジュアル面談の申し込み
Podcast kyash.fm

子育てソフトフェアエンジニア、家を買い換える

f:id:gettergot:20210818175811j:plain

まえがき

Fintechベンチャーでサーバサイドエンジニアをしている @uncle__ko です
この度、都内に所有していたマンション(居住用)を売却し、戸建て(居住用)を購入しました
かなり大変だったのと色々と知見を得られたのでブログに残しておこうかなと思い、今回この記事を書いてみました
ちなみにエンジニア要素は特にないのですw
*1

なぜ買い換える?

コロナ渦で在宅ワークになり、家にいる時間が増えました
通勤もあまりしなくなり、家で快適に仕事が出来て、プライベートも充実させたいと考えるようになり、都内のマンションより郊外の戸建てに住んだほうが僕や家族のライフスタイルにはあっているかなと思ったのがきっかけです
また、引越すなら娘が小学校に上がる前には引越しておきたいというのもありました

さあ、家探しだ!

要件の整理

間取り

僕の家族構成を説明すると、夫婦+子供1人です
いまのところ子供を増やす予定はありません
僕も妻もITエンジニアでリモートワークなので仕事部屋は欲しいです
ただ、1人1部屋ほしいかと言われると、1年間リモートワークをしてみた感想だと欲しいけど必須ではないという感覚です
また、子供部屋は1部屋ほしいです

まとめると

  • 夫婦の寝室
    • 1
  • 子供部屋
    • 1
  • 仕事部屋
    • 1

があれば問題ないということになります

つまり、3LDK以上の建物
ということになります

立地

僕も妻も田舎の出身で、都会より田舎がよいという考えでした
僕は持病の喘息やアトピーもあり、田舎のほうが過ごしやすいというのもあります
また、自然の中で子育する方が子供にもいいのかなという思考をもっていました(人によると思うので、あくまで個人の感覚です)
そして、リモートワークであることもあり都心に住む理由もない
ただ、いつまでもリモートワークとは限りません
最悪、出社になっても通える範囲が理想

さらに僕が海沿いの出身で海が好きなので海の近くならいいな
という思いもありました

まとめると
郊外だけど都心にギリギリ通える範囲がよい
さらに海近だと最高
という立地で探すことにしました

マンションか戸建てか

f:id:gettergot:20210818175905j:plain

もともと高い建物より地に足をつけていたいタイプの人間なので低層のマンション or 戸建てがよいと思ってました
また、子供が庭で遊べたほうがいいよなとか考えたり、車が好きで10代の頃から車を所有しているので、出来れば洗車が出来る戸建てがいいかなと思いました

まとめると
戸建てが理想
ということです

まとめ

ここまでをまとめると
3LDK以上の間取りで、ある程度田舎だけど、最悪都心へ通える範囲の海が近い戸建て
ということになります

売却だ!

https://1.bp.blogspot.com/-rFpZh9viF6s/VwIpfsKEZ4I/AAAAAAAA5i4/g0ok-LCitpMlkI-tTYSsRZznRstI6tNCQ/s400/job_fudousan_kanteishi.png

欲しい物件の要件が整理できても、すでに所有しているマンションを売却しなければ、しがないエンジニアの自分では新しい家を買うことはできません
なので売却からスタートします

住み替えの方法

まず、住み替えるには2通りの方法があります

  • 買い先行
  • 売り先行

です

買い先行

そのままですね
先に欲しい物件なり土地を探すなりして買ってしまい、売りを後で行う形です
メリデメは下記

  • メリット
    • いくら時間を掛けてもいいのでじっくり家探しができる
    • 仮住まいがいらない
  • デメリット
    • 2重ローンを組む可能性が高い
    • 売却がかけ足になるので売却金額が安くなりやすい

売り先行

それもそのままです
先に所有している物件を売却してから物件を購入することになります

メリデメは下記

  • メリット
    • 売却に時間を使えるので買い手との売却額の交渉がしやすい(高値で売れる可能性がある)
    • 2重ローンにならないので資金計画は立てやすい
  • デメリット
    • 仮住まいを挟むことになる可能性が高い

どちらを選択したか?

理想は同時進行で売りと買いを同時に実施したい
また、リスクは最小限で進めたい
という理由で売り先行で実施しました
*2

売却の仲介業者探し

suumoも一括査定で地元の不動産屋と大手の不動産屋と希望してる買い替え先の不動産屋に頼みました

suumo.jp

どこにお願いしたか?

自分は最後まで買いと売りのタイミングを同日に行うことを諦めたくなかったので大手で全国に支店がある大手の不動産屋に仲介をお願いしました

媒介契約

不動産の売却を正式に依頼する際には、不動産仲介会社と媒介契約を締結することが必要になります
売却時の媒介契約とは、宅地建物取引業者が不動産を売却しようとする者との間で締結する契約です

不動産仲介会社は、宅地建物取引業法によって依頼者との媒介契約の締結が義務付けられてます
依頼者が不動産仲介会社にどのようなサービスを受けるのか?、また仲介手数料はいくらか?などを明記することで、仲介時のトラブルを未然に防ぐ目的があります

媒介契約は下記3種類があります

  • 専属専任媒介契約
  • 専任媒介契約
  • 一般媒介契約

それぞれのメリデメを書いていきます

専属専任媒介契約

専属専任媒介契約は売却活動を1社に任せる契約となります
業務報告義務があったり仲介手数料が絶対もらえるので不動産仲介会社の中での優先度は高くなる傾向にあります

  • メリット
    • レインズ*3への登録が5営業日以内
    • 業務報告義務が1週間に1回以上
  • デメリット
    • 自分で買主を見つけたとしても仲介手数料は支払わなければならない
    • 囲い込みをされる可能性がある
      • 売り買いどちらからも仲介手数料を取るために囲い込みを行う悪い不動産会社もいるかもしれないです

専任媒介契約

専属専任媒介契約と同様に、売却活動を1社に任せる契約となります
違いとしては、売り主自ら見つけてきた相手との取引は仲介手数料を払わなくていい点です
ただし、複数社との契約はできません

  • メリット
    • レインズへの登録が7営業日以内
    • 業務報告義務が2週間に1回以上
  • デメリット
    • 囲い込みをされる可能性がある
      • 売り買いどちらからも仲介手数料を取るために囲い込みを行う悪い不動産会社もいるかもしれないです

一般媒介契約

一般媒介契約は、複数の会社に売却活動を依頼できる契約となります
不動産仲介会社の中での優先度は低くなる傾向にあります
競合してがんばってもらえると思いきや、色々と面倒なのと手数料をもらえない可能性があるので、実は優先度を下げられたりします

  • メリット
    • 複数の不動産会社と契約できる
  • デメリット
    • レインズへの登録が任意
    • 業務報告も任意

結局どの媒介契約にしたの?

専属専任媒介契約でお願いしました
理由としては出来るだけ高く売却したかったので専属でお願いしたくて、マンション内に知り合いもいなかったし、不動産購入したい知り合いもいなかったので、専属専任でいいかなって思って契約しました

売却額の設定

持ち主は自分なので好きな額に設定することができます
言ってしまえば購入額の2倍で売りに出しても文句は言われません
とはいえその金額だと誰も購入してはくれないでしょう

周りの相場や、同じマンションの過去の売却額等を考慮しつつ金額を設定していきます

現状、都内のマンション価格は上がり続けていて、自分の所有していたマンションは相場を見ても購入金額より高く売却できそうな感じでした
これはとても運が良かったと思います
ですので指値されることも見越して相場よりも少し高い金額で売りに出しました

売却活動スタート

売りに出して最初の週末には5組の内覧がありました
また、次の週には3組の内覧がありました

その中の1組の方に指値なしで購入いただき2週間で売却が完了することになりました
ただ、この方も買い替えでした
そのため、もし、指値なしで申し込みをしてくれた方に売却する場合は仮住まいを余儀なくされます
とはいえ、指値なしだと利益がある程度見込めるため仮住まいを挟んで売却することにしました

購入だ!

https://1.bp.blogspot.com/-nl6Li1Z-P8I/VpjCk0Z8lrI/AAAAAAAA3DQ/ISdp9j0fvJ8/s400/house_ie_sagashi.png

思ったより早く売却が完了してしまい、急いで購入物件を探すことになりました また、仮住まいを挟まなければいけないので、出来るだけ早く住めることが条件となりました

住宅ローンの事前審査

自分達の収入から予算はある程度把握していましたが借りられなければ買えません 適当な予算にあった物件でネット銀行とメガバンク地方銀行の事前審査を通しておきました これにより、思い描いてる予算で自分が物件を探せることがわかるので早めに行っておきました

住宅ローンの金利タイプ

f:id:gettergot:20210818180119j:plain

住宅ローンを調べると最初に出てきてみんな悩む金利タイプを書いておきます それぞれの考えがあるのと、どちらが正解というのもないと思ってるのと、僕はFP(ファイナンシャルプランナー)でもなんでもないので、どちらがいいとかの言及は避けておきます

固定金利

固定金利はずっと同じ金利

  • 全期間固定金利
    • メリット
      • 完済までの返済金額が確定しているため、返済計画が立てやすい
      • 金利の低い時期に契約すると、最終支払いまで低金利のまま
    • デメリット
      • 一般的に、変動金利型に比べて金利が高めに設定されている
  • 固定金利期間選択型
    • 最初の契約時に2年、5年、10年などの期間を選び、その期間の金利を固定するタイプ
    • メリット
      • 固定金利期間中は返済額が変わる心配がなく、また変動金利型のような未払利息のリスクもない
    • デメリット
      • 固定期間が終了すると、その時点の金利金利タイプを選択し直すのでその後の返済額は最初にローンを組んだ時点ではわからない
      • 返済開始後の金利の変動によっては将来の返済額が変わる可能性がある
変動金利

変動金利を選べば金利は定期的に変わる

  • メリット
    • 金利水準が下がり、ローンに適用される金利も下がると、将来の返済額は少なくなる
    • 通常半年ごとに金利が見直されるが金利が大きく上昇した場合でも返済額は通常5年ごとに見直すためすぐに家計に影響することが避けらる
  • デメリット
    • 金利の変動によって将来の返済額が変わる可能性があり、ローンを組んだ時点では返済総額がいくらになるかはわからない
    • 多くの金融機関では半年ごとに金利の見直しが行われるが、元利均等返済の場合は返済額の見直しは5年ごとになっているため金利が上昇すると、返済額のうち金利が占める割合が高くなるので元金があまり減らないということも考えられる
    • 金利の上昇度合いによっては、本来支払わなければいけない利息部分の金額が返済額を上回る「未払利息の発生」の危険性がある

伏兵、保育園の転園問題現る

https://2.bp.blogspot.com/-JE-zVpHjbKo/WMdcg40zONI/AAAAAAABChg/7xNrmKSTMb85O06UH7nskGTMARLJO83bgCLcB/s450/hoikujo_ninka.png

娘は都内の認可保育園に通っています 出来る限り、引越し後も認可保育園に通わせたいです ただ、ここが苦労したポイントなので諸々まとめていきたいと思います

保育園の入園日

保育園は月の途中からの入園は出来ず、毎月1日に受け入れる方針でした*4

転園申請の提出期限

転園申請を出して、審査を実施し問題がなければ転園ができます 審査は転園も入園も関係なく毎月10日に申請書が役所に届いている人が対象になります そのことから転園したい月の前月10日には申請書を出しておく必要があります

申請資料

これは自治体によるので自分で調べる必要がありますが、僕の引越し先の自治体では、住民票 or 引越してくることがわかる書類(賃貸借契約書 or 不動産売買契約書)が必要でした 不動産売買契約書については売却ではなく、購入の不動産売買契約書が必要です(売却では引越してくる証拠にはならないので)

保育園に在籍できる条件

保育園に在籍できる条件には 「月の1日に住民票が保育園のある自治体にあること」 というものがあります

総合すると

上記の条件と我が家のスケジュールを総合して考えると
売却の引き渡しが6月半ばであったため6/1には転園したい
6/1に転園するのであれば、5月10日には役所に転園申請資料が到着してなければならない
転園申請資料には住民票 or 引越してくることがわかる書類(賃貸借契約書 or 不動産売買契約書)が必要
5月はGWがあるので4月末には資料の準備が完了している必要がある

ということになります

賃貸契約

4月までに家を買うのはさすがに不可能なので賃貸契約をすることにしました
賃貸契約をすると、6月の引き渡しまではローン返済が続くので家賃とローン返済が2重で請求されます
しかも5月末までは住むこともないです
ここまでしたところで、審査次第では転園できないかもしれません
とはいえ認可保育園に入れるためなら背に腹は代えられないのです

購入活動スタート

保育園の転園問題のスケジュールは見えたので家の購入を進めていきます
このスケジュールでやっていくので僕の中では注文住宅の選択肢は消えて行きました

物件の情報収集

コロナ禍になり、僕のように住まいを見直す世帯が増えたことにより不動産業界はかつてないバブル状態です
建売住宅が土地の段階で買われてくような状態でした

常にsuumoも見ながら生活しつつ、3つくらいの不動産屋に探してもらいました

保育園の転園の承認

このタイミングで転園の承認がおりてすごく安心したのを覚えています

購入物件に出会う

そんな中、6月完成予定の理想的な立地の建売住宅を見つけることができました
しかも、普段は注文住宅を作っている工務店がモデルハウスとして作った建売だったの、で設備も仕様も豪華でおしゃれでした
中々土地も建売も出ない立地だったので即決しました

売買契約

購入の売買契約を行います 重要事項説明等を受けつつたくさんの印鑑を押していきます 売却よりは難しくないです

引越し

ここで賃貸に引越して、保育園に通いはじめました

住宅ローンの本審査

こちらは事前審査で通っていた中で条件が良かった銀行で行いました
ネット銀行がよかったのですが、3ヶ月くらい審査にかかる状況でスケジュールに合わないため地方銀行に出しました

そして無事に審査は通過しました

金銭消費貸借契約

www.athome.co.jp

銀行からお金を借りて物件を買うための契約です

内覧

完成した物件を最終チェックします ホームインスペクションを入れる方もいるので検討するのもいいと思います

www.jshi.org

個人的には、契約前にホームインスペクションを入れられない日本の不動産購入フローには違和感を覚えます 思想が売り主に寄りすぎてバランスバグってる気がしますね 欧米では契約前にホームインスペクションを実施するのが一般的です

引き渡し

f:id:gettergot:20210818171527j:plain

f:id:gettergot:20210818171602j:plain

無事、家が引き渡されました!

まとめ

今回、不動産の買い替えを経験してみてかなりハードルが高いなと思いました
特に保育園の転園周りはかなり大変でした
今回は運と入念な準備のおかげで、なんとか無事に買い替えを行うことができました
買い替え期間は何かと有給を使うことも多く、チームメンバーにはご迷惑をお掛けしました
サポートありがとうございました
さすがにもう買い換えることもないだろうとは思いつつ、なかなか出来ない経験かと思うのでいい経験が出来たと思ってます

売却益が出てる関係で今年の確定申告はめんどくさい予感はしますが、忙しい時期は終わったので、のんびりと海の近くの生活を楽しんでいきたいと思います

*1: 注意事項: 僕は不動産について素人なので個人的見解の記事です。マンションがいいとか戸建てがいいとか賃貸がいいとかはそれぞれのライフスタイルに依ると思うので特に触れないです

*2:ちなみに買い替え特約をつけることも出来たりしますが、断られることもあったりします。詳しくは調べて見てください

*3:レインズ(REINS)とは「Real Estate Information Network System」の頭文字「REINS」を示したもので、不動産物件情報交換のためのネットワークシステムを指します

*4:僕の自治体の話であり自治体によるのかもしれません