2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

スタンバイAdvent Calendar 2024

Day 4

Vespaの冗長化を試してみる

Last updated at Posted at 2024-12-03

はじめに

スタンバイアドベントカレンダー4日目です:smiley:

スタンバイでは検索エンジンにVespaを利用しています!
Vespaはmulti-node構成をとることで冗長化することができます。
スタンバイでも冗長化構成をとっています。

本記事では冗長化構成であるmulti-nodeの公式サンプルが用意されているので、それを用いて環境構築します。
環境構築後、content clusterの冗長化について検証していきたいと思います。content clusterはdocumentを管理しています。
※document:Vespaはデータをドキュメントとしてモデル化しています。本記事でデータの意味を表します。

各clusterの役割

サンプルを実施する前にVespaの各clusterについて簡単に説明をします。

image.png
画像出典: Vespa Overview

cluster 役割
Admin/Config 設定の管理や各clusterの制御の役割
Stateless Java container ユーザからの検索リクエストや更新を受け付ける役割
Content indexを保持し検索・ランキングを実行する役割

公式サンプル実施!

環境準備

公式サンプルの最初からStart the content cluster:まで実施します。ここまで実施すると動作確認できる状態になっています。
※サンプルの中でstatusの確認をする場面が何度かでてきますが、数十秒待たないと反映されないこともあるのでご注意ください。

このサンプルでは、contaier-clusterを2つにわけています。feed(更新)query(検索)を独立して作成しています。

動作確認

feed(更新)

documentAPIを利用してdocumentのfeedをします。このサンプルでは5件feedします。

i=0; (for doc in $(ls ../../../album-recommendation/ext/*.json); \
  do \
    curl -H Content-Type:application/json -d @$doc \
    http://localhost:8080/document/v1/mynamespace/music/docid/$i; \
    i=$(($i + 1)); echo; \
  done)

query(検索)

feedしたdocumentが検索できることを確認します。

curl --data-urlencode 'yql=select * from sources * where sddocname contains "music"' \
  http://localhost:8082/search/

以下のように返却されることを確認します。
image.png

contentの冗長性

contentの冗長性について確認していきます。

デプロイはサンプルにあったコマンドを実行します。
(以降デプロイする時はこのコマンドを実行)

zip -r - . -x "gke/*" "img/*" "scripts/*" "pki/*" "tls/*" README.md .gitignore "*.yaml" | \
  curl --header Content-Type:application/zip --data-binary @- \
  http://localhost:19071/application/v2/tenant/default/prepareandactivate

content内のドキュメント数

各nodeのドキュメント数を確認するのにVespaが提供するmonitorAPIを利用します。

サンプルだとnode8とnode9がcontent-nodeなので対象portにリクエストを投げます。
content-nodeを増やす場合はportsを更新してください。

ports=(20100 20101)

for port in "${ports[@]}"; do
  curl -s "http://localhost:$port/metrics/v2/values" | \
  jq -r '.nodes[] | .hostname as $hostname | .services[] | select(.name == "vespa.searchnode") | .metrics[] | select(.values["content.proton.documentdb.documents.active.last"]) | "\($hostname): \(.values["content.proton.documentdb.documents.active.last"])"'
done

実行するとnode8に2件、node9に3件保持していることがわかります。(node8が3件になることもあるかもしれません)

node8.vespanet: 2
node9.vespanet: 3

min-redundancy

概要

サンプルでは<min-redundancy>2</min-redundancy>となっています。

min-redundancyとはdocumentをコピーして保持する数となります。つまり、いずれかのcontentが壊れてもdocumentを保持します。

以下のパターンを検証します。

  • 特定nodeにおけるVespaサービスの停止
  • コンテナ停止
  • コンテナ削除

検証

冗長性あり(min-redundancy:2)

  • 特定nodeにおけるVespaサービスの停止
    node9のVespaサービスを停止してみます。
docker exec -it node9 /bin/bash
[vespa@node9 /]$ vespa-stop-services
config-sentinel was running with pid 99, sending SIGTERM
Waiting for exit (up to 15 minutes)
.. DONE
configproxy was running with pid 33, sending SIGTERM
Waiting for exit (up to 15 minutes)
. DONE

ドキュメント数を確認してみるとnode8のdocumentが5件になっていることがわかります。なので検索しても5件表示されます。

node8.vespanet: 5

node9のVespaを再開させます

[vespa@node9 /]$ vespa-start-services
Starting config proxy using tcp/node0.vespanet:19070 and tcp/node1.vespanet:19070 and tcp/node2.vespanet:19070 as config source(s)
Waiting for config proxy to start on 'node9.vespanet'
runserver(configproxy) running with pid: 587
config proxy started after 0s (runserver pid 587)
Starting services for VESPA_HOSTNAME='node9.vespanet'
runserver(config-sentinel) running with pid: 653

数秒待つと、ドキュメント数は以前と同じ状態になります。

node8.vespanet: 2
node9.vespanet: 3
  • コンテナ停止
docker stop node9

Vespaサービスの停止と同じ動作になります。

  • コンテナ削除
docker rm -f node9

削除後にnode9を再度docker runし、再度デプロイします。

docker run --detach --name node9 --hostname node9.vespanet \
    -e VESPA_CONFIGSERVERS=node0.vespanet,node1.vespanet,node2.vespanet \
    --network vespanet \
    --publish 19108:19107 --publish 20101:19092 \
    vespaengine/vespa services

Vespaサービスの停止と同じ動作になります。

冗長性なし(min-redundancy:1)

services.xmlを修正して、デプロイします。
※抜粋

    <content id="music" version="1.0">
        <min-redundancy>1</min-redundancy>
        <documents>
            <document type="music" mode="index" />
            <document-processing cluster="feed" />            
        </documents>
        <nodes>
            <node hostalias="node8" distribution-key="0" />
            <node hostalias="node9" distribution-key="1" />
        </nodes>
    </content>
  • 特定nodeにおけるVespaサービスの停止
    先ほどと同じようにnode9のVespaサービスを停止して、ドキュメント数を確認します。
node8.vespanet: 2

先ほどと違い冗長化されていないため、node8のdocumentが2件のままとなっています。なので検索しても2件しか返却されません。
image.png

  • コンテナ停止
    Vespaサービスの停止と同じ動作になります。

  • コンテナ削除
    削除後にnode9を再度docker runし、再度デプロイします。

node8.vespanet: 2
node9.vespanet: 0

冗長化していた時と違い、document数が戻りません。

Vespaのdocument情報はvespa-remove-indexで記載されている通り$VESPA_HOME/var/db/vespa/に格納されているため、コンテナを削除すると削除されます。
Vespaサービスの停止とコンテナ停止は$VESPA_HOME/var/db/vespa/の情報が削除されないため、documentが復活するということがわかりました。

group

先ほどはcontentのnode1台ずつ独立して分散していましたが、
content-nodeをグループ化して分散することも可能です。
content用のコンテナを追加で作成します。

docker run --detach --name node10 --hostname node10.vespanet \
    -e VESPA_CONFIGSERVERS=node0.vespanet,node1.vespanet,node2.vespanet \
    --network vespanet \
    --publish 19109:19107 --publish 20102:19092 \
    vespaengine/vespa services

docker run --detach --name node11 --hostname node11.vespanet \
    -e VESPA_CONFIGSERVERS=node0.vespanet,node1.vespanet,node2.vespanet \
    --network vespanet \
    --publish 19110:19107 --publish 20103:19092 \
    vespaengine/vespa services

hosts.xmlにnode10とnode11を追加します。
※抜粋

  <host name="node10.vespanet">
    <alias>node10</alias>
  </host>
  <host name="node11.vespanet">
    <alias>node11</alias>
  </host>

services.xmlにnode10とnode11を追加します。
※抜粋

    <content id="music" version="1.0">
        <min-redundancy>2</min-redundancy>
        <documents>
            <document type="music" mode="index" />
            <document-processing cluster="feed" />            
        </documents>
        <group>
            <distribution partitions="1|*"/>
            <group name="group0" distribution-key="0">
                <node hostalias="node8" distribution-key="0"/>
                <node hostalias="node9" distribution-key="1"/>
            </group>
            <group name="group1" distribution-key="1">
                <node hostalias="node10" distribution-key="2"/>
                <node hostalias="node11" distribution-key="3"/>
            </group>
        </group>
    </content>

この状態でデプロイします。(グループ数とmin-redundancyの数やdistribution partitionsの設定が正しくないとエラーになります)
デプロイ後、各コンテナのdocument数を確認するとグループ単位に冗長化されていることが確認できました。

node8.vespanet: 2
node9.vespanet: 3
node10.vespanet: 3
node11.vespanet: 2

最後に

content clusterの冗長化について確認し、共有させていただきました。
スタンバイでもcontent clusterのnode数や冗長化構成は負荷に合わせて試行錯誤しながら調整をしています。

Vespaを利用する側として、今後も学んで最適な構成で利用していきたいです!

最後までお読みいただき、誠にありがとうございました。

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?