エンタープライズシステムと連携して顧客データを継続的に名寄せ

高橋洸(以下、高橋):みなさんこんばんは、引き続きSansanの高橋が「究極の名寄せのためのサーバーレスアーキテクチャ」と題して、発表いたします。よろしくお願いします。

自己紹介、高橋と申します。

前職が中堅のSIerで、Sansanに入って2年ちょっとで、ふだんはWebまわりを触っています。マサカリ歓迎でございます。先ほども会社を出る前に、うちのアーキテクトからマサカリをすでに投げられてきて参ってしまったんですけど、宜しくお願いします。

本日は、まずSansan Customer Intelligenceのサービス概要と、「このサービスがどのような背景でどういった思想のもとアーキテクチャになっているか」という話をします。

Sansan Customer Intelligence、先ほど加畑の説明で「SansanのプロダクトとしてSansanとEightというプロダクトがある」という話をしたのですが、このSansan Customer Intelligence はまだローンチから2ヶ月たっていないんです。つい先日に公開されたばかりの新しいサービスんなんですけれども、弊社の人間以外で聞いたことあるっていう方……? まあいないですよね。

では、これを簡単に説明いたします。これは一言で言うと、「エンタープライズシステムと連携して顧客データを継続的に名寄せする」という、だいぶかたい表現をしてますがマルチテナントのBtoBサービスです。

ユーザーが利用するクラウドサービスと連携をして、「クラウドサービス」って言っていますけれども、CSVでもいいです。もしかすると、オンプレかもしれない。そのサービスと連携しまして、貰ってきたデータの各レコードを組織であったり人物の単位で名寄せしていくといったサービスです。

Sansanのオプション機能という位置づけなのですが、システムとしては全く別のシステムとなっております。ユーザーのシステムからデータを抜いていきます、名寄せします、そしてデータを溜めます、そしてこれをWebで表示したり元のシステムに書き込みにいったりする、というシステムです。

名寄せ名寄せと言っているのに申し訳ありませんが、名寄せの仕組みについては企業秘密ということで、よろしくお願いします。

名寄せにおける課題

高橋:このシステムはどんな課題を解決をするのかというところを簡単に説明します。大きくポイントが3つありまして、まず1つ目が汚くなる営業管理システムです。

何かと言いますと、営業さんが営業管理をしていて、こっちの人が「NEC」と登録し、こちらの人が「日本電気」と登録したとすると、これはよくある話らしいのですが、本当は同じ会社なのに別のオブジェクト、別の取引先ととらえられてしまう。これは困った。ということです。

別々の取引先にどんどんレポートが紐付いていくのだけれども実は同じ会社だったということがよくあるらしいです。これを「NEC」と「日本電気」は同じ企業ですと名寄せしてくれるというのが大きな特長です。

次に、名刺交換を超えた「早く言ってよ」です。これはみなさんCMでご覧になったことがある方も多いかと思いますが、名刺交換を実は社内でしていたんだけどそのことに気が付けなかったということをSansanが名刺を超えてやろうと。

営業さん「ある会社に営業かけたくてSansanを見たけれども社内で誰も名刺交換をしていないらしい」と。一方で問い合わせ担当の人から「実は問い合わせが来てましたよ」となって、営業さんが「早く言ってよ!」という状況ですね。

これを営業管理のシステム、Sansanの名刺、問い合わせ情報を持ってきて1つの画面で見えるようにすれば、検索すれば名刺はないけど問い合わせがきていることがわかるということです。

3つ目は、顧客情報の不足です。データが統合されたけれども、住所や規模がわからないから、営業戦略がたてられないよという状況です。

かといっていちいちWebで探すのもコストです。これに対しユーザーが持っている情報にさらにプラスして、登記簿から住所や正式名をとってきたり、帝国データバンクさんの情報を使って従業員数やを取得して企業規模を把握できるようにしたり、あるいは関連会社やグループ会社の情報を使って、既存顧客にグループ会社があるけれどもまだ名刺交換してませんというような集合的に見れるようになるというのがサービスの3つ目の大きなポイントです。

このサービスの価値は、やっぱりなにより名寄せです。名寄せで困っていない企業はほぼないと思います。そこで弊社がこれまで4億枚の名刺データの入力で培ってきた名寄せの技術、ノウハウを使ってこの課題を解決しようではないかというところがこのサービスの価値です。

名寄せサービスのアーキテクチャ

ここからはアーキテクチャについてお話します。このサービスのアーキテクチャを一言で言うと、「ドメイン駆動設計風のマイクロサービスアーキテクチャ的なやつ」で、だいぶフワッとした表現になっています。マイクロサービスアーキテクチャ的なやつをやるに先立てて、1番重要なところが「サービスをどの単位で分割するか」というところになってくるわけです。

これをドメイン駆動設計でいうBounded Contextに沿って分割しましょうという発想に基づいております。Microsoftのアーキテクチャガイドだったり有名な『Building Microservices』という本でも推奨されている方法です。

Building Microservices: Designing Fine-Grained Systems

このBounded Contextというのは、外部とのインターフェイスが決まっている領域で、その領域の境界を丁寧に設計して、その中で最適な実装をもちましょうという発想です。

名寄せ基盤について

高橋:これから、ドメインをどう区切っていくかを考えていくのですが、先ほどお見せしたこの図をもう一度みてみます。ユーザーのシステムからデータを持ってきて名寄せして、保存して、Webから参照できるようにしたり、書き込みをしたり、ということを行う必要があります。これは「ETLプラスα」ということができます。ETL、Extract/Transform/Loadです。

Extractは複数システムからのデータを抽出する。Transformはとってきたデータを変換します。今回のサービスでいうと名寄せになります。そして変換したデータをデータストアに保存するのがLoadとなっています。

なので、こちらの基盤の概念というか枠組みを利用して、ドメインを区切っていこうではないかというところで、具体的にドメインはこのようになりました。

Connectorは、連携システムとインターフェイスするドメインです。連携システムのSansanや営業管理のサービスの連携するサービスがあるとどんどん増えていきます。

次がETLで、データを取ってきて保存するところです。そしてデータを書きもどすというところをPublishingと呼んでいます。

そして、Webです。図で書くと大体こんな感じです。ConnectorがいてETLにまわして、ETLはデータを保存します。それをWebから参照したりPublishingのほうに回したり。Publishingは元のConnectorに戻ります。PublishやExtractという名称は、ドメイン間で同じ名前が重複してきてわかりにくいところがあると思うのですが、それぞれのドメインの中の1つの言語ということです。

サービスを分割するメリット

高橋:先ほども申し上げましたけれどもConnectorというのは連携システムの数だけ増えていきます。Extractから複数の線がでてきたり、Publishingからも複数の線がでてきます。この境界のインターフェイスをスキーマで規定してあげる必要があります。今回はメッセージやデータベースでスキーマで定義しております。

全体の流れで言うとこのようなワークフローになっていて、まず先方のシステムがあり、そのAPIからデータを取ってきます。ConnectorのドメインとETLのドメインはメッセージがインターフェイスしていて、続いて社内の名寄せAPIをたたいて名寄せしてこれを保存します。

そして保存したデータとWebの間はElasticsearchがインターフェイスになってます。そして保存すると、Publishingのほうに回ってきてデータベースに対してこんなデータを返してくれというのを作って、それをPublishに返してあげるということです。

さて、サービスを分割してなんとなくきれいになりましたが、何がうれしいのかというとまず可用性の向上です。先ほどの図で、仮にどこかが落ちていたとしても、全体としては止まりません。今回複数のAPIを叩く必要があるので、障害になるポイントが多くなるわけですが、それを分散しましょうというところです。

次に独立したデプロイというところ。ドメインを分けていて、それぞれ別々のリポジトリで管理しているので、片方が動いている状態で片方がデプロイということが可能になります。また開発も分担できるようになります。それぞれのドメインでそれぞれ並行して開発ができます。

あとは個別のスケーリングというところで、「このサービスのこのファンクションのところだけ負荷が高くなっているから性能がいいやつに変えよう」みたいなことが可能になります。

サービスのバグを調査するのが大変

高橋:各サービスで最適な技術選定ができるというところもメリットです。今はほぼ全体がC#なんですけどWebのところはNode.jsで書いてあったり、C#じゃなくてもそれぞれ適した方法を使ってもいいし、何を使ってもいいというところで選べるということになっています。

ただし当然いいことばかりではなくて、どうしても複雑になってしまいます。テストが大変だったり、何かバグっぽいことが起こって、このサービスでエラーがおきたときに、そのサービスのバグなのかどこか前段のサービスで作ったメッセージが悪くてエラーになっているのかみたいなさかのぼって調査することが非常に大変になってきます。

また、インターフェイスを変えないといけなくなったときに、それぞれどこをどうやって変えればいいのかというところが大変になってきます。また、サービスをまたいだトランザクションが使えないというところで、どうしても結果整合モデルの実装が必要になってくるんですけど、これをどうやって実現するかというところも丁寧に設計する必要があります。今回はインターフェイスとしてメッセージを使用しているのがほとんどなわけですけど、同じメッセージを流しても同じ結果になるように保たなければいけないというところです。

そして、マイクロサービス的な分割をしたわけですが、果たしてこれが正しかったのかというのはわかりません。というのもサービスもまだスタートしたばかりですし、今後どんどん状況が変わってくるかもしれないからです。

書籍等で紹介されていますが、「1回モノリスを構築してから分割しましょう」という話があるんですね。今回は最初からサービスを分割したわけですが、ETLという既存の枠組みにしたがったので、非常に作りやすかったですし、単純なワークフローでしたというところもありました。ここまでさんざんドメイン駆動やマイクロサービスといってきたのですが、その手法に特にこだわりはありません。それぞれの特長を生かすことが目的です。

やりたいこともまだまだたくさんあります。ワークフロー管理、BI、Webフロントエンド……ということでエンジニア募集中ですので、興味がありましたらお声掛けください。ありがとうございました。