<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>山本 博之 (Hiroyuki Yamamoto) &#8211; SRA OSS Tech Blog</title>
	<atom:link href="https://www.sraoss.co.jp/tech-blog/author/yamamoto/feed/index.xml" rel="self" type="application/rss+xml" />
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<description>OSS専門の技術ブログ。PostgreSQL、Zabbixを中心に10種類以上のOSSの解説、アップデート情報、運用ヒントを提供。</description>
	<lastBuildDate>Thu, 22 Oct 2026 07:44:44 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2018/07/blog-icon-150x150.png</url>
	<title>山本 博之 (Hiroyuki Yamamoto) &#8211; SRA OSS Tech Blog</title>
	<link>https://www.sraoss.co.jp/tech-blog/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Zabbix 5.2の紹介</title>
		<link>https://www.sraoss.co.jp/tech-blog/zabbix/zabbix52-newfeature/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Wed, 04 Nov 2020 05:30:41 +0000</pubDate>
				<category><![CDATA[Zabbix]]></category>
		<category><![CDATA[OSS]]></category>
		<category><![CDATA[Zabbix 5.0]]></category>
		<category><![CDATA[Zabbix 5.2]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=6467</guid>

					<description><![CDATA[本記事では、2020/10/27にリリースされたZabbix 5.2で追加された機能や変更点について解説します。 Zabbix 5.2の変更点は以下のページに記載されています。 5 What&#8217;s new in ...]]></description>
										<content:encoded><![CDATA[<p>本記事では、2020/10/27にリリースされたZabbix 5.2で追加された機能や変更点について解説します。</p>
<p>Zabbix 5.2の変更点は以下のページに記載されています。</p>
<p><span id="more-6467"></span></p>
<p><a id="sindexmenu_21066228065f22b696d92e07" class="navSel" title="5 What's new in Zabbix 5.2.0" href="https://www.zabbix.com/documentation/5.2/manual/introduction/whatsnew520">5 What&#8217;s new in Zabbix 5.2.0</a><br />
<a href="https://www.zabbix.com/rn/rn5.2.0">Release Notes for Zabbix 5.2.0</a></p>
<p>Zabbix 5.2 はポイントリリースとなり、サポート期間が短いため、実運用では LTS バージョンの利用を推奨します。</p>
<p>Zabbix 5.2 の主な変更点を以下に挙げます。</p>
<h2>Scriptアイテムタイプ</h2>
<p><a href="https://www.zabbix.com/documentation/current/manual/config/items/itemtypes/script">Scriptアイテムタイプ</a>が追加されました。ユーザー定義のJavaScriptによりHTTP/HTTPSでデータを収集することが可能です。</p>
<p><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-6556" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/b10ee1e689af6a02ab5065e2cbec7944.png" alt="" width="893" height="480" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/b10ee1e689af6a02ab5065e2cbec7944.png 893w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/b10ee1e689af6a02ab5065e2cbec7944-300x161.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/b10ee1e689af6a02ab5065e2cbec7944-768x413.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/b10ee1e689af6a02ab5065e2cbec7944-304x163.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/b10ee1e689af6a02ab5065e2cbec7944-282x152.png 282w" sizes="(max-width: 893px) 100vw, 893px" /></p>
<h2>タイムゾーン設定</h2>
<p>フロントエンドのタイムゾーンの設定をグローバルおよびユーザーごとに設定できるようになりました。これまではphpの設定ファイルでのみ指定可能でした。</p>
<p><img decoding="async" class="alignnone size-full wp-image-6486" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/1a12e98bac758b90795c0c7186190068.png" alt="" width="579" height="375" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/1a12e98bac758b90795c0c7186190068.png 579w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/1a12e98bac758b90795c0c7186190068-300x194.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/1a12e98bac758b90795c0c7186190068-304x197.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/1a12e98bac758b90795c0c7186190068-282x183.png 282w" sizes="(max-width: 579px) 100vw, 579px" /></p>
<h2>シークレット(秘密情報)の保存</h2>
<p>パスワードなどの秘密情報を<a href="https://www.vaultproject.io/">HashiCorp Vault</a>という外部サービスに保存できるようになりました。この値はユーザーマクロとデータベースの認証情報で使用できます。</p>
<p><img decoding="async" class="alignnone size-full wp-image-6473" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09.png" alt="" width="967" height="234" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09.png 967w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-300x73.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-768x186.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-304x74.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-282x68.png 282w" sizes="(max-width: 967px) 100vw, 967px" /></p>
<h2>ユーザーロール(ユーザーの役割)</h2>
<p><a href="https://www.zabbix.com/documentation/current/manual/web_interface/frontend_sections/administration/user_roles">ユーザーロール(ユーザーの役割)</a>を定義できるようになりました。これによりWeb UIの各機能、APIへのアクセス、障害発生時のアクションへのアクセスなど、細かいユーザー権限の制御が可能になりました。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-6557" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/f609df4fdbbdbc2abd3102555694f7f6.png" alt="" width="1000" height="431" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/f609df4fdbbdbc2abd3102555694f7f6.png 1000w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/f609df4fdbbdbc2abd3102555694f7f6-300x129.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/f609df4fdbbdbc2abd3102555694f7f6-768x331.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/f609df4fdbbdbc2abd3102555694f7f6-304x131.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/f609df4fdbbdbc2abd3102555694f7f6-282x122.png 282w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6558" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/c0fbe445958eec8a6f3c27362b99a271.png" alt="" width="600" height="578" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/c0fbe445958eec8a6f3c27362b99a271.png 944w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/c0fbe445958eec8a6f3c27362b99a271-300x289.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/c0fbe445958eec8a6f3c27362b99a271-768x740.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/c0fbe445958eec8a6f3c27362b99a271-222x214.png 222w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/c0fbe445958eec8a6f3c27362b99a271-270x260.png 270w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<h2>YAMLファイルのエクスポート・インポート</h2>
<p>Zabbixの各種設定をこれまでのXML・JSONに加え、YAML形式でエクスポート・インポートが行えるようになりました。YAMLは可読性が高く、編集も行いやすい形式です。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-6475" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-08-2.png" alt="" width="565" height="289" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-08-2.png 565w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-08-2-300x153.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-08-2-304x155.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-08-2-282x144.png 282w" sizes="auto, (max-width: 565px) 100vw, 565px" /></p>
<p>YAML形式でエクスポートしたテンプレートの内容は以下のようになります。</p>
<pre>zabbix_export:
  version: '5.2'
  date: '2020-10-08T08:29:52Z'
  groups:
    -
      name: Templates/Applications
  templates:
    -
      template: 'Template App Apache by HTTP'
      name: 'Template App Apache by HTTP'
      description: |
        Get metrics from mod_status module using HTTP agent.</pre>
<h2>MQTTプロトコルへの対応</h2>
<p><a href="https://mqtt.org/">MQTT</a>プロトコルに対応したZabbix agent 2アイテム mqtt.get[] が追加されました。MQTTはIoT向けの軽量なPub/Sub型のデータ配信プロトコルです。</p>
<p>mqtt.get[] アイテムは以下のように使用します。対象のトピックを購読し、文字列もしくはJSON(トピックをワイルドカードで指定した場合)で取得します。</p>
<pre>mqtt.get["<a href="https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/src/go/plugins/mqtt/README.md" rel="nofollow">tcp://host:1883</a>","path/to/topic"]
mqtt.get["<a href="https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/src/go/plugins/mqtt/README.md" rel="nofollow">tcp://host:1883</a>","path/to/#"]
mqtt.get["<a href="https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/src/go/plugins/mqtt/README.md" rel="nofollow">ws://host:8080</a>","path/to/topic"]</pre>
<h2>Webフロントエンド</h2>
<h3>タブの情報表示</h3>
<p>フロントエンドの各種ページのタブに設定済み項目数や有効状態が表示されるようになりました。タブを開かなくても設定の有無が簡単に分かるようになりました。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-6477" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/01d1abb653660caab2e39ea57799bf3e.png" alt="" width="685" height="312" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/01d1abb653660caab2e39ea57799bf3e.png 685w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/01d1abb653660caab2e39ea57799bf3e-300x137.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/01d1abb653660caab2e39ea57799bf3e-304x138.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/01d1abb653660caab2e39ea57799bf3e-282x128.png 282w" sizes="auto, (max-width: 685px) 100vw, 685px" /></p>
<h3>フィルター設定の保存</h3>
<p>障害およびホストのページでフィルターの設定が保存できるようになりました。保存したフィルターはタブで切り替えることができます。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-6509" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/4a512971e852fe3a26bf1d05f259792d.png" alt="" width="780" height="325" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/4a512971e852fe3a26bf1d05f259792d.png 780w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/4a512971e852fe3a26bf1d05f259792d-300x125.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/4a512971e852fe3a26bf1d05f259792d-768x320.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/4a512971e852fe3a26bf1d05f259792d-304x127.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/4a512971e852fe3a26bf1d05f259792d-282x118.png 282w" sizes="auto, (max-width: 780px) 100vw, 780px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-6510" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/44da24938a63e7795f4fd6d6365bbc13.png" alt="" width="500" height="219" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/44da24938a63e7795f4fd6d6365bbc13.png 500w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/44da24938a63e7795f4fd6d6365bbc13-300x131.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/44da24938a63e7795f4fd6d6365bbc13-304x133.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/44da24938a63e7795f4fd6d6365bbc13-282x124.png 282w" sizes="auto, (max-width: 500px) 100vw, 500px" /></p>
<h3>セッションをcookieに保持</h3>
<p>フロントエンドのセッション情報をWebサーバ上ではなくユーザーのcookieに暗号化して保持するようになりました。これによりフロントエンドを動作させるWebサーバのロードバランスが可能になります。</p>
<h3>インターフェースのないホストが作成可能</h3>
<p>インターフェースのないホストが作成できるようになりました。トラッパーアイテムやWebチェックのみ使用するホストで有用です。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-6479" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-2.png" alt="" width="561" height="224" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-2.png 561w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-2-300x120.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-2-304x121.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/2020-10-09-2-282x113.png 282w" sizes="auto, (max-width: 561px) 100vw, 561px" /></p>
<h3>メンテナンス期間ページの簡略化</h3>
<p>これまで複数のタブに分かれていたメンテナンス期間の設定ページが1つのページにまとまり、操作性が向上しました。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-6482" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/392b8b05c7831c2dedcd4532c22530f2.png" alt="" width="933" height="896" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/392b8b05c7831c2dedcd4532c22530f2.png 933w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/392b8b05c7831c2dedcd4532c22530f2-300x288.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/392b8b05c7831c2dedcd4532c22530f2-768x738.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/392b8b05c7831c2dedcd4532c22530f2-223x214.png 223w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/10/392b8b05c7831c2dedcd4532c22530f2-271x260.png 271w" sizes="auto, (max-width: 933px) 100vw, 933px" /></p>
<h2>その他の改良点</h2>
<p>その他以下のような改良が行われています。</p>
<ul>
<li>エージェントのHostnameパラメータに複数のホスト名を記述して、1つのエージェントから複数のホストとしてアクティブチェックを行えるようになりました。これにより1つの物理サーバ上の独立したアプリケーションなどを従来のように複数のエージェントを起動することなく論理的な複数のホストとして分割できます。</li>
<li>Modbusプロトコルに対応したアイテムが追加されました。</li>
<li>HTTPエージェントとWebシナリオがダイジェスト認証に対応しました。</li>
<li>アイテムのエラーを保存前処理で上書きできるようになりました。</li>
<li>ホストプロトタイプでインターフェースを指定できるようになりました。</li>
<li>ホストプロトタイプがタグに対応しました。</li>
<li>エージェントの設定パラメータにUserParameterのディレクトリを指定するUserParameterDirが追加されました。</li>
<li>SNMPアイテムのテストでバージョン固有のパラメータが指定できるようになりました。</li>
<li>取得不可アイテムの更新間隔のグローバルな設定が削除され、各アイテムの更新間隔が使用されるようになりました。</li>
<li>ユーザーマクロの長さが255から2048文字に拡張されました。</li>
<li>フロントエンドのデフォルトの言語をインストール時および管理設定で設定できるようになりました。</li>
<li>以前はdefines.inc.phpファイルを編集することでのみ設定できた一部のパラメータがフロントエンドで直接設定できるようになりました。</li>
<li>ダッシュボードの一覧にフィルターが追加されました。</li>
<li>長期間の分析のためのトリガー関数が追加されました。</li>
<li>テンプレートのスクリーンがダッシュボードに変換されました。</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Zalando Postgres Operatorの紹介</title>
		<link>https://www.sraoss.co.jp/tech-blog/pgsql/zalando-postgres-operator/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Tue, 20 Oct 2020 03:37:07 +0000</pubDate>
				<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Zalando]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=6094</guid>

					<description><![CDATA[本記事では、コンテナ管理ツールのKubernetes上でPostgreSQLのHAクラスタを構築できるZalando Postgres Operatorについて解説します。 Zalando Postgres Operat ...]]></description>
										<content:encoded><![CDATA[<p>本記事では、コンテナ管理ツールのKubernetes上でPostgreSQLのHAクラスタを構築できるZalando Postgres Operatorについて解説します。</p>
<p><span id="more-6094"></span></p>
<h2>Zalando Postgres Operatorとは</h2>
<p><a href="https://github.com/zalando/postgres-operator">Zalando Postgres Operator</a> (以下 Postgres Operator)は、コンテナの管理ツールである<a href="https://kubernetes.io/">Kubernetes</a>上でHA構成のPostgreSQLクラスタを容易に構築できるようにするoperatorです(operatorはKubernetesの機能を拡張するプラグインのような機構です)。本ソフトウェアはドイツのファッション系eコマース企業である<a href="https://www.zalando.se/">Zalando SE</a>によって開発され、自社のサービスで運用されています。本ソフトウェアはMITライセンスの元公開されています。</p>
<h3>Operatorについて</h3>
<p>OperatorはKubernetes上で動作するアプリケーションの各種管理を自動化するための機能です。従来システム管理者が手動で行っていた、監視、障害時の対応、バックアップ、スケーリングといった様々な操作をプログラムとして記述し、Kubernetesに組み込むことでKubernetesの動作を拡張できます。</p>
<p>また、PostgreSQLに新たなoperatorが必要となるもう一つの要因として、PostgreSQLクラスタはプライマリとレプリカ(スタンバイ)の役割を考慮する必要があり、ステートレスなアプリケーション(例:Webサーバ)のように簡単にレプリカ(複製)を複数台用意することができないことが挙げられます。</p>
<h3>Postgres Operatorの機能</h3>
<p>Postgres Operatorによりストリーミングレプリケーションを用いたプライマリ1台、レプリカ(スタンバイ)複数台のPostgreSQLクラスタを簡単に構築することができます。</p>
<figure id="attachment_6097" aria-describedby="caption-attachment-6097" style="width: 1111px" class="wp-caption alignnone"><img loading="lazy" decoding="async" class="size-full wp-image-6097" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_arch_1.png" alt="" width="1111" height="557" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_arch_1.png 1111w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_arch_1-300x150.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_arch_1-1024x513.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_arch_1-768x385.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_arch_1-304x152.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_arch_1-282x141.png 282w" sizes="auto, (max-width: 1111px) 100vw, 1111px" /><figcaption id="caption-attachment-6097" class="wp-caption-text">Zalando Postgres Operatorの構成</figcaption></figure>
<p>Postgres Operatorの主な機能は以下になります。</p>
<ul>
<li>PostgreSQL HAクラスタの管理</li>
<li>ストリーミングレプリケーション (同期・非同期)</li>
<li>コネクションプール (PgBouncer使用)</li>
<li>フェイルオーバー (pg_rewindにより高速な復旧が可能)</li>
<li>ローリングアップデート</li>
<li>論理バックアップ (S3使用)</li>
<li>WALアーカイブ・PITR (WAL-E、S3使用)</li>
</ul>
<h3>Zalando社による講演</h3>
<p>PGCon 2020カンファレンスイベントにてZalando社により行われた講演の資料が公開されています。こちらもあわせて参照ください。<br />
<a href="https://www.pgcon.org/events/pgcon_2020/schedule/session/106-postgresql-on-k8s-at-zalando-two-years-in-production/">PostgreSQL on K8s at Zalando: Two years in production</a></p>
<h2>検証環境</h2>
<p>本記事ではKubernetesのマネージドサービスである<a href="https://aws.amazon.com/jp/eks/">Amazon EKS</a>上でZalando Postgres Operatorを動作させます。<br />
本記事では以下の構成で解説を行います。</p>
<ul>
<li>Kubernetes: Amazon EKS (Kubernetesのマネージドサービス)</li>
<li>ワーカーノード: t3.medium 2ノード</li>
<li>アーカイブ用ストレージ: Amazon S3</li>
<li>作業環境: CentOS 8.1 (VirtualBox上のVM)</li>
</ul>
<p>なお、EKSクラスタの作成は既に完了しているものとします。EKSの使用方法については<a href="https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/what-is-eks.html">こちら</a>を参照ください。</p>
<h2>検証内容</h2>
<p>今回はPostgres Operatorの以下の項目について確認しました。</p>
<ul>
<li>Postgres Operator のデプロイ</li>
<li>Web UI</li>
<li>PostgreSQL クラスタの作成</li>
<li>PostgreSQLの動作確認</li>
<li>フェイルオーバー</li>
<li>スケーリング</li>
<li>ローリングアップグレード</li>
<li>論理バックアップ</li>
<li>WALアーカイブ・PITR</li>
<li>ログ</li>
</ul>
<h2>Postgres Operatorのデプロイ</h2>
<p>Postgres OperatorはKubernetesとしては基本的な構成のため、導入は比較的簡単です。</p>
<p>Githubのリポジトリを作業環境にcloneします(もしくはtarballを展開します)。</p>
<pre>$ git clone https://github.com/zalando/postgres-operator.git
$ cd postgres-operator/</pre>
<p>グローバルな設定はconfigmap.yamlファイルに記述されているので、必要に応じて修正します。<br />
ここではバックアップ先のS3の設定などのグローバルな設定を記述します。</p>
<p>kubectl create -fで各YAMLファイルを適用していきます。</p>
<pre>$ kubectl create -f configmap.yaml
$ kubectl create -f operator-service-account-rbac.yaml
$ kubectl create -f postgres-operator.yaml
$ kubectl create -f api-service.yaml</pre>
<p>オブジェクトが作成され、正常に動作していることを確認します。</p>
<pre>$ kubectl get all
NAME                                     READY   STATUS    RESTARTS   AGE
pod/postgres-operator-85978df8cf-zqwjd   1/1     Running   0          48s

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/kubernetes          ClusterIP   10.100.0.1       &lt;none&gt;        443/TCP    168m
service/postgres-operator   ClusterIP   10.100.197.174   &lt;none&gt;        8080/TCP   22s

NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/postgres-operator   1/1     1            1           48s

NAME                                           DESIRED   CURRENT   READY   AGE
replicaset.apps/postgres-operator-85978df8cf   1         1         1       49s</pre>
<h2>Web UI</h2>
<p>Postgres OperatorにはWeb UIが同梱されており、ブラウザから以下の操作が可能です。</p>
<ul>
<li>クラスタの作成・削除</li>
<li>複製</li>
<li>設定編集</li>
<li>状態確認</li>
</ul>
<figure id="attachment_6099" aria-describedby="caption-attachment-6099" style="width: 1383px" class="wp-caption alignnone"><img loading="lazy" decoding="async" class="size-full wp-image-6099" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/Screenshot_2020-06-25-PostgreSQL-Operator-UI.png" alt="" width="1383" height="944" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/Screenshot_2020-06-25-PostgreSQL-Operator-UI.png 1383w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/Screenshot_2020-06-25-PostgreSQL-Operator-UI-300x205.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/Screenshot_2020-06-25-PostgreSQL-Operator-UI-1024x699.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/Screenshot_2020-06-25-PostgreSQL-Operator-UI-768x524.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/Screenshot_2020-06-25-PostgreSQL-Operator-UI-304x208.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/Screenshot_2020-06-25-PostgreSQL-Operator-UI-282x192.png 282w" sizes="auto, (max-width: 1383px) 100vw, 1383px" /><figcaption id="caption-attachment-6099" class="wp-caption-text">Postgres Operator UI</figcaption></figure>
<p>Web UIのデプロイは同様にkubectlを使用して行います。</p>
<pre>$ kubectl create -f ui/manifests/</pre>
<h2>Postgresクラスタの作成</h2>
<p>PostgresクラスタのデプロイはYAMLファイルを作成して適用するか、前述のWeb UIで作成操作を行います。</p>
<p>サンプルのYAMLファイルが同梱されていますので、それを元に設定ファイルを作成します。</p>
<ul>
<li>minimal-postgres-manifest.yaml: 最小限の設定</li>
<li>complete-postgres-manifest.yaml: 各種設定を網羅</li>
<li>standby-manifest.yaml: スタンバイ専用クラスタ設定</li>
</ul>
<p>基本的な設定を含む設定ファイルは以下になります。</p>
<pre>apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
  name: sraoss-minimal-cluster           # クラスタ名の指定
spec:
  teamId: "sraoss"
  volume:
    size: 1Gi                            # ボリュームサイズの指定
  numberOfInstances: 2                   # インスタンス数(マスター+レプリカ)の指定
  users:                                 # DBユーザーの作成
    zalando:  # database owner
    - superuser
    - createdb
    foo_user: []  # role for application foo
  databases:                             # データベースの作成
    foo: zalando  # dbname: owner
  preparedDatabases:
    bar: {}
  postgresql:
    version: "12"                        # PostgreSQLバージョンの指定(9.6～12)
  enableLogicalBackup: true              # 論理バックアップの有効化
  logicalBackupSchedule: "30 00 * * * *" # cron形式のバックアップスケジュール
  enableConnectionPooler: true           # コネクションプールの有効化
  connectionPooler:
    numberOfInstances: 2</pre>
<p>これに加え、PostgreSQLのpostgresql.conf、pg_hba.confに相当する追加の設定を行うこともできます。</p>
<pre>...
  postgresql:
    version: "12“
    parameters:                          # postgresql.conf内のパラメータの指定
      shared_buffers: "64MB"
      max_connections: "50"
      log_statement: "all“
  patroni:
    initdb:                              # initdb時のパラメータの指定
      encoding: "UTF8"
      locale: "ja_JP.UTF-8"
      data-checksums: "true"
    pg_hba:                              # pg_hba.conf内のパラメータの指定
    - hostssl all all 0.0.0.0/0 md5
    - host    all all 0.0.0.0/0 md5</pre>
<p>同様にkubectlで適用します。</p>
<pre>$ kubectl create -f test-postgres-manifest.yaml</pre>
<p>クラスタの状態を確認します。numberOfInstances: 2の場合は2つのPodが作成されます。各Podがmasterかreplicaかはspilo-roleラベルで確認できます。</p>
<pre>$ kubectl get postgresql
NAME                     TEAM     VERSION   PODS   VOLUME   CPU-REQUEST   MEMORY-REQUEST   AGE    STATUS
sraoss-minimal-cluster   sraoss   12        2      1Gi                                     113s   Running

$ kubectl get pods -l application=spilo -L spilo-role
NAME                       READY   STATUS    RESTARTS   AGE     SPILO-ROLE
sraoss-minimal-cluster-0   1/1     Running   0          2m19s   master
sraoss-minimal-cluster-1   1/1     Running   0          95s     replica</pre>
<h2>PostgreSQLの動作確認</h2>
<p>Kubernetesクラスタ内の他のPodからは上記のmasterおよびreplicaにアクセスすることができます。</p>
<p>作業環境からpsqlでアクセスしたい場合はkubectlのport-forward機能を利用します。<br />
※ PGMASTERにはmasterのPod名が入ります。</p>
<pre>$ export PGMASTER=$(kubectl get pods -o jsonpath={.items..metadata.name} -l application=spilo,cluster-name=sraoss-minimal-cluster,spilo-role=master)
$ kubectl port-forward $PGMASTER 6432:5432</pre>
<p>別端末からlocalhost:6432に接続します。なお、接続時にはSSLが必須となります。<br />
※ パスワードはPostgresクラスタ作成時に自動生成されます。</p>
<pre>$ kubectl get secret postgres.sraoss-minimal-cluster.credentials -o 'jsonpath={.data.password}' | base64 -d
(パスワード文字列が表示される)
$ export PGSSLMODE=require
$ psql -U postgres -h localhost -p 6432
ユーザ postgres のパスワード:(上記パスワード文字列)
postgres=# create table t (t text); postgres=# insert into t values ('hoge'); postgres=# select * from t; t ------ hoge (1 行)</pre>
<h2>フェイルオーバー</h2>
<p>masterのPodに故障が発生した場合は、自動的にフェイルオーバーしてreplicaがmasterに昇格します。これはPostgres Operatorが使用している、SpiloというPostgreSQLおよびHAを実現するためのテンプレート(Patroni)を含むDockerイメージにより実現しています。</p>
<p>master Podを削除した場合は元replicaがmasterに昇格し、削除したPodが再作成されてreplicaとして復帰します。データサイズが少ない状態ではあるものの、フェイルオーバーは数10秒程度ですばやく完了します。</p>
<pre>$ kubectl delete pod sraoss-minimal-cluster-0
pod "sraoss-minimal-cluster-0" deleted

$ kubectl get pods -l application=spilo -L spilo-role
NAME                       READY   STATUS              RESTARTS   AGE   SPILO-ROLE
sraoss-minimal-cluster-0   0/1     ContainerCreating   0          6s
sraoss-minimal-cluster-1   1/1     Running             0          12m   master

$ kubectl get pods -l application=spilo -L spilo-role
NAME                       READY   STATUS    RESTARTS   AGE   SPILO-ROLE
sraoss-minimal-cluster-0   1/1     Running   0          23s   replica
sraoss-minimal-cluster-1   1/1     Running   0          12m   master</pre>
<p>masterのプロセス故障が発生した場合は元replicaがmasterに昇格し、元masterはPodを維持したままプロセスを再起動しreplicaに降格します。以下の例ではmaster Pod内に入り、initプロセスを停止させて疑似的にプロセス故障を起こしています。</p>
<pre>$ kubectl exec sraoss-minimal-cluster-0 -it /bin/sh
# kill 1</pre>
<h2>スケーリング</h2>
<p>デプロイ済みのPostgresクラスタの設定を変更すると、変更内容に応じてクラスタの状態を自動的に追従させます。<br />
クラスタのPodの数を指定するnumberOfInstancesを2から3に変更すると、Statefulsetsのレプリカ数も2から3に変更され、新しいreplica Podが起動します。</p>
<pre>$ kubectl edit postgresql
spec:
  <strong>numberOfInstances: 2 -&gt; 3 に修正</strong>

$ kubectl get postgresql
NAME                     TEAM     VERSION   PODS   VOLUME   CPU-REQUEST   MEMORY-REQUEST   AGE   STATUS
sraoss-minimal-cluster   sraoss   12        <strong>3</strong>      1Gi                                     53m   Running
$ kubectl get statefulsets
NAME                     READY   AGE
sraoss-minimal-cluster   <strong>3/3</strong>     14m
$ kubectl get po -l application=spilo -L spilo-role
NAME                       READY   STATUS    RESTARTS   AGE     SPILO-ROLE
sraoss-minimal-cluster-0   1/1     Running   0          50m     master
sraoss-minimal-cluster-1   1/1     Running   0          50m     replica
<span style="color: #0000ff;"><strong>sraoss-minimal-cluster-2   1/1     Running   0          7m21s   replica</strong></span></pre>
<h2>ローリングアップデート</h2>
<p>PostgreSQLのマイナーバージョンアップ(Dockerイメージの更新)、およびPostgreSQLの設定変更はローリングアップデートによりサービスの停止なしに行うことができます。なお、メジャーバージョンアップはローリングアップデートでは行えないため、ベースバックアップからクラスタの複製により行う必要があります。</p>
<figure id="attachment_6107" aria-describedby="caption-attachment-6107" style="width: 258px" class="wp-caption alignnone"><img loading="lazy" decoding="async" class="wp-image-6107 size-medium" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_rollupd-258x300.png" alt="" width="258" height="300" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_rollupd-258x300.png 258w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_rollupd-184x214.png 184w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_rollupd-224x260.png 224w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_rollupd.png 351w" sizes="auto, (max-width: 258px) 100vw, 258px" /><figcaption id="caption-attachment-6107" class="wp-caption-text">ローリングアップデート</figcaption></figure>
<p>以下、Dockerイメージを更新した場合にローリングアップデートが行われる様子を実際に確認してみます。</p>
<h3>Dockerイメージの更新</h3>
<pre>$ kubectl edit postgresql sraoss-test-cluster
  dockerImage: (旧Dockerイメージ) -&gt; (新Dockerイメージ)
  postgresql:
    version: "12"
</pre>
<h3>ローリングアップデート開始</h3>
<pre>$ kubectl get postgresql
NAME                  TEAM     VERSION   PODS   VOLUME   CPU-REQUEST   MEMORY-REQUEST   AGE     STATUS
sraoss-test-cluster   sraoss   12        2      1Gi                                     9m19s   <strong>Updating</strong>

$ kubectl get pods -l application=spilo -L spilo-role
NAME                    READY   STATUS        RESTARTS   AGE     SPILO-ROLE
sraoss-test-cluster-0   1/1     Running       0          9m24s   master
sraoss-test-cluster-1   1/1     <strong>Terminating</strong>   0          8m42s

$ kubectl get pods -l application=spilo -L spilo-role
NAME                    READY   STATUS              RESTARTS   AGE     SPILO-ROLE
sraoss-test-cluster-0   1/1     Running             0          9m34s   master
sraoss-test-cluster-1   0/1     <strong>ContainerCreating</strong>   0          8s</pre>
<h3>元replica Podが再作成され、masterに昇格</h3>
<pre>$ kubectl get pods -l application=spilo -L spilo-role
NAME                    READY   STATUS    RESTARTS   AGE     SPILO-ROLE
sraoss-test-cluster-0   1/1     Running   0          9m39s
<strong>sraoss-test-cluster-1   1/1     Running   0          13s     promoted</strong></pre>
<h3>元master Podの再作成</h3>
<pre>$ kubectl get pods -l application=spilo -L spilo-role
NAME                    READY   STATUS        RESTARTS   AGE     SPILO-ROLE
sraoss-test-cluster-0   1/1     <strong>Terminating</strong>   0          9m49s
sraoss-test-cluster-1   1/1     Running       0          23s     <strong>master</strong>

$ kubectl get pods -l application=spilo -L spilo-role
NAME                    READY   STATUS              RESTARTS   AGE   SPILO-ROLE
sraoss-test-cluster-0   0/1     <strong>ContainerCreating</strong>   0          4s
sraoss-test-cluster-1   1/1     Running             0          30s   master</pre>
<h3>元master Podがreplicaとして復帰</h3>
<pre>$ kubectl get pods -l application=spilo -L spilo-role
NAME                    READY   STATUS    RESTARTS   AGE   SPILO-ROLE
<strong>sraoss-test-cluster-0   1/1     Running   0          14s   replica</strong>
sraoss-test-cluster-1   1/1     Running   0          40s   master</pre>
<h2>論理バックアップ</h2>
<p>Postgres Operatorでは定期的にAmazon S3に論理バックアップ(pg_dumpall)を取ることができます。なお、論理バックアップからの自動リストア機能はないので、リストアはクラスタ作成後手動で行う必要があります。</p>
<p>前述のconfigmap.yamlでバックアップ先のS3の設定を行います。</p>
<pre>logical_backup_s3_bucket: "zalando-backup"
logical_backup_s3_access_key_id: "xxxxxxxxxxxxxxxx"
logical_backup_s3_secret_access_key: "xxxxxxxxxxxxxxxx</pre>
<p>Postgresクラスタの設定で論理バックアップを有効にします。スケジュールはcron表記で指定します(以下は毎日0:30に実行)。</p>
<pre>  enableLogicalBackup: true
  logicalBackupSchedule: “30 00 * * *"</pre>
<p>指定時刻にKubernetesのCronJobとしてバックアップが実行されます。</p>
<pre>$ kubectl get cronjob
NAME                                    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
logical-backup-sraoss-minimal-cluster   30 00 * * *   False     0        6m48s           27m

$ kubectl get job
NAME                                               COMPLETIONS   DURATION   AGE
logical-backup-sraoss-minimal-cluster-1593418800   1/1           3s         6m46s

$ kubectl describe job logical-backup-sraoss-minimal-cluster-1593418800
...
Pods Statuses:  0 Running / 1 Succeeded / 0 Failed</pre>
<p>S3の以下の場所にバックアップファイルがアップロードされます。</p>
<pre>s3://&lt;bucket-name&gt;/spilo/&lt;cluster-name&gt;/&lt;UUID&gt;/logical_backups/&lt;job ID&gt;.sql.gz</pre>
<h2>WALアーカイブ・PITR</h2>
<p>前述のconfigmap.yamlでバックアップ先のS3の設定を行います。なお、EKSクラスタからS3 bucketへのアクセスが許可されている必要があります。</p>
<pre>wal_s3_bucket: "zalando-wal-backup"</pre>
<p>S3の以下の場所にWALがアーカイブされます。</p>
<pre>s3://&lt;bucket-name&gt;/spilo/&lt;cluster-name&gt;/&lt;UUID&gt;/wal/basebackups_00x/
s3://&lt;bucket-name&gt;/spilo/&lt;cluster-name&gt;/&lt;UUID&gt;/wal/wal_00x/</pre>
<p>S3のバックアップからクラスタを複製(clone)することでPITRが可能です。PITRの復元位置を指定することもできます。</p>
<pre>spec:
  clone:
    uid: "efd12e58-5786-11e8-b5a7-06148230260c"
    cluster: “sraoss-test-cluster"
    timestamp: "2017-12-19T12:40:33+01:00"</pre>
<figure id="attachment_6110" aria-describedby="caption-attachment-6110" style="width: 600px" class="wp-caption alignnone"><img loading="lazy" decoding="async" class="wp-image-6110" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_wal_clone-300x91.png" alt="" width="600" height="183" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_wal_clone-300x91.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_wal_clone-768x234.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_wal_clone-304x93.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_wal_clone-282x86.png 282w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/07/zalando_wal_clone.png 974w" sizes="auto, (max-width: 600px) 100vw, 600px" /><figcaption id="caption-attachment-6110" class="wp-caption-text">WALアーカイブからのclone</figcaption></figure>
<h2>ログ</h2>
<p>Postges Operator自体はログ管理に関する機能を持ちません。Podのsidecarコンテナをユーザが追加することは可能なので、ログ収集のための補助コンテナを導入し、fluentdと連携するなどの作り込みは必要となります。また、Kubernetesクラスタのログを集約するKubernetes Log WatcherというツールがZalando社によって公開されています。</p>
<p>クラスタの各Podのログはkubectl logsコマンドにより確認できます。</p>
<pre>$ kubectl logs sraoss-minimal-cluster-0</pre>
<p>また、Pod内のPostgreSQLログは以下のように格納されています。</p>
<pre>/home/postgres/pgdata/pgroot/pg_log/
-rw-r--r-- 1 postgres postgres      0 Jun 29 06:12 postgresql-0.csv
-rw-r--r-- 1 postgres postgres 277783 Jun 29 06:58 postgresql-1.csv
-rw-r--r-- 1 postgres postgres    205 Jun 29 06:12 postgresql-1.log
-rw-r--r-- 1 postgres postgres      0 Jun 29 06:12 postgresql-2.csv
-rw-r--r-- 1 postgres postgres      0 Jun 29 06:12 postgresql-3.csv
-rw-r--r-- 1 postgres postgres      0 Jun 29 06:12 postgresql-4.csv
-rw-r--r-- 1 postgres postgres      0 Jun 29 06:12 postgresql-5.csv
-rw-r--r-- 1 postgres postgres      0 Jun 29 06:12 postgresql-6.csv
-rw-r--r-- 1 postgres postgres      0 Jun 29 06:12 postgresql-7.csv</pre>
<h2>おわりに</h2>
<p>手動でPostgreSQL HAクラスタを構築するとなるとかなりの手間がかかります。また、Kubernetes上にそれを構築しようとするのはかなり困難です。Zalando Postgres Operatorを用いることで、Kubernetes上のPostgreSQL HAクラスタの構築が非常に容易になります。実際に開発元のサービスで運用されている実績があり、機能的にまだ不十分なところもあるものの、フェイルオーバーなどの重要な機能に関してはしっかりと作り込まれていると感じました。今後の発展が楽しみなソフトウェアといえます。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/pgsql-mainte/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-pgsql" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、PostgreSQL/Pgpool-II のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Kubernetes PostgreSQL Operatorの紹介</title>
		<link>https://www.sraoss.co.jp/tech-blog/pgsql/kubernetes-postgres-operator/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Tue, 20 Oct 2020 03:28:37 +0000</pubDate>
				<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=6386</guid>

					<description><![CDATA[本記事では、コンテナ管理ツールであるKubernetes上でPostgreSQLクラスタを動かすためのOperatorと呼ばれるソフトウェアについて概要を紹介します。また、代表的なPostgreSQL Operatorと ...]]></description>
										<content:encoded><![CDATA[<p>本記事では、コンテナ管理ツールであるKubernetes上でPostgreSQLクラスタを動かすためのOperatorと呼ばれるソフトウェアについて概要を紹介します。また、代表的なPostgreSQL OperatorとしてZalandoとCrunchyを紹介します。各ソフトウェアの詳細については以下の記事を参照ください。</p>
<p><span id="more-6386"></span></p>
<ul>
<li><a href="https://www.sraoss.co.jp/tech-blog/pgsql/crunchy-postgresql-operator/">Crunchy PostgreSQL Operatorの紹介</a></li>
<li><a href="https://www.sraoss.co.jp/tech-blog/pgsql/zalando-postgres-operator/">Zalando Postgres Operatorの紹介</a></li>
</ul>
<h2>Kubernetesの特長</h2>
<p>Kubernetesは宣言的設定(マニフェスト)で「あるべき状態」を定義することにより自律的にシステムの管理を行うことが特長です。例えばWebサーバのレプリカ数を3とした場合、現在の状態を定期的にチェックし、サーバの数がそれに満たない場合は新たに起動します。この繰り返しの動作をReconciliation Loop(突合せループ)と呼びます。</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6425 size-full" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_reconloop.png" alt="Reconciliation Loop" width="1384" height="552" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_reconloop.png 1384w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_reconloop-300x120.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_reconloop-1024x408.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_reconloop-768x306.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_reconloop-304x121.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_reconloop-282x112.png 282w" sizes="auto, (max-width: 1384px) 100vw, 1384px" /></p>
<p>Kubernetesでは、これまでシステム管理者が手作業で行っていたサーバの構築と運用管理を自動化することができます。例えば以下のような作業です。</p>
<ul>
<li>定期バックアップ・リストア</li>
<li>スケールアウト・スケールイン</li>
<li>ローリングアップデート</li>
</ul>
<h2>Kubernetes上でPostgreSQLを運用するメリット</h2>
<p>従来のPostgreSQLデータベースの管理は以下のような問題を抱えていました。</p>
<ul>
<li>HA クラスタ環境の構築が面倒</li>
<li>監視、バックアップ、障害対策など、運用の手間がかかる</li>
<li>負荷の急な増加に即座に対応できない</li>
<li>データ量増加に伴うディスク容量の不足</li>
<li>テスト・開発環境の用意が大変</li>
</ul>
<p>Kubernetes上でPostgreSQLを運用すると以下のようなメリットがあります。</p>
<ul>
<li>PostgreSQL HA クラスタ環境を自動的に構築・運用管理できる</li>
<li>PostgreSQL の検証環境・テスト環境をすぐに構築・削除できる</li>
<li>バックアップ・リカバリの自動化</li>
<li>負荷に応じて、レプリカの台数を増減可能</li>
<li>Namespace により、PostgreSQL クラスタをサービスごとに隔離可能 (Multi-Tenant)</li>
<li>高可用性・耐障害性の向上 (Multi-Cluster、Multi-Zone)</li>
<li>必要に応じて、ボリューム<i>サイズ</i>拡張可能</li>
<li>PostgreSQLのバージョン管理が容易</li>
</ul>
<h2>PostgreSQL Operator</h2>
<h3>Operatorとは</h3>
<p>Operatorとは、Kubernetesの機能を拡張し、様々な運用管理の手順をコードとして記述したものです。Operatorにより、運用の自動化が可能になります。</p>
<h3>PostgreSQL Operator</h3>
<p>PostgreSQL OperatorはPostgreSQLのデプロイ、バックアップ、障害対応、クラスタ管理、監視などの管理タスクを自動化します。PostgreSQL Operatorの基本的な構成は以下のようになります。</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6427 size-full" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure.png" alt="PostgreSQL Operatorの基本構成図" width="1642" height="758" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure.png 1642w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure-300x138.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure-1024x473.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure-768x355.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure-1536x709.png 1536w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure-304x140.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_basicstructure-282x130.png 282w" sizes="auto, (max-width: 1642px) 100vw, 1642px" /></p>
<h3>PostgreSQL Operatorの活用例</h3>
<h4>バックアップ</h4>
<p>バックアップジョブを定期的に実行してDBのバックアップを行うことができます。また、WALアーカイブを随時保存します。取得したバックアップやWALアーカイブはAmazon S3(もしくはその互換サービス)に保存できます。</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6532 size-full" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_backup2.png" alt="定期バックアップ" width="1098" height="631" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_backup2.png 1098w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_backup2-300x172.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_backup2-1024x588.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_backup2-768x441.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_backup2-304x175.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_backup2-282x162.png 282w" sizes="auto, (max-width: 1098px) 100vw, 1098px" /></p>
<h4>バックアップから複数のテスト環境を複製</h4>
<p>保存しておいたWALアーカイブから環境を復元できます。また、これを利用して本番環境のバックアップから複数の環境を複製して、テスト環境として用いるといった用途にも使えます。</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6533 size-full" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2.png" alt="バックアップから複製" width="1545" height="753" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2.png 1545w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2-300x146.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2-1024x499.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2-768x374.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2-1536x749.png 1536w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2-304x148.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_clone2-282x137.png 282w" sizes="auto, (max-width: 1545px) 100vw, 1545px" /></p>
<h4>高可用性:クラスタ内フェイルオーバー</h4>
<p>プライマリのPodに障害が発生した場合、レプリカの1つが自動的にプライマリに昇格します。元プライマリのPodはレプリカに降格して動作を続けます。また、Podが削除された場合は自動的に新しいPodが再作成されます。</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6433" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo-300x300.png" alt="フェイルオーバー" width="400" height="399" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo-300x300.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo-150x150.png 150w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo-215x214.png 215w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo-261x260.png 261w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo.png 678w" sizes="auto, (max-width: 400px) 100vw, 400px" /></p>
<h4>高可用性:クラスタ間フェイルオーバー</h4>
<p>2つの独立したKubernetesクラスタ間で、S3に保存したWALアーカイブ経由でPostgreSQLのアクティブ・スタンバイクラスタが同期を取ります。アクティブ側のクラスタに障害が発生した場合は手動でフェイルオーバーを行います。</p>
<p>Kubernetesクラスタを物理的に独立した場所に分散配置することでディザスタリカバリに利用することができます。</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6435 size-full" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo_cluster.png" alt="クラスタ間フェイルオーバー" width="1234" height="798" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo_cluster.png 1234w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo_cluster-300x194.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo_cluster-1024x662.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo_cluster-768x497.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo_cluster-304x197.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_fo_cluster-282x182.png 282w" sizes="auto, (max-width: 1234px) 100vw, 1234px" /></p>
<h4>スケーリング</h4>
<p>設定変更によりレプリカの数を動的に増減させることができます。レプリカ数を増やした場合、不足分のレプリカPodが自動的に作成されます。レプリカ数を減らした場合は、余分なレプリカPodが削除されます。</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-6437" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_scale.png" alt="スケーリング" width="400" height="371" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_scale.png 699w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_scale-300x278.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_scale-231x214.png 231w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/09/pgonk8s_scale-280x260.png 280w" sizes="auto, (max-width: 400px) 100vw, 400px" /></p>
<h2>ZalandoとCrunchyについて</h2>
<p>現在開発が続けられている代表的なPostgreSQL OperatorとしてZalandoとCrunchyがあります。ここではそれぞれの特長について概要を紹介します。各Operatorの詳細については別記事を参照ください。</p>
<h3>基本情報</h3>
<table width="1401">
<tbody>
<tr>
<td width="211"></td>
<td width="595"><b>Zalando</b></td>
<td width="595"><b>Crunchy</b></td>
</tr>
<tr>
<td width="211"><b>開発元</b></td>
<td width="595">Zalando SE</td>
<td width="595">Crunchy Data</td>
</tr>
<tr>
<td width="211"><b>ライセンス</b></td>
<td width="595">MIT License</td>
<td width="595">Apache License 2.0</td>
</tr>
<tr>
<td width="211"><b>対応バージョン</b></td>
<td width="595">PostgreSQL 9.6+</td>
<td width="595">PostgreSQL 9.5+</td>
</tr>
<tr>
<td width="211"><b>動作環境</b></td>
<td width="595">Amazon AWS, Google Cloud, OpenShift</td>
<td width="595">Amazon AWS, Google Cloud, OpenShift, VMWare Enterprise, IBM Cloud Pak Data</td>
</tr>
<tr>
<td width="211"><b>URL</b></td>
<td width="595"><a href="https://github.com/zalando/postgres-operator">https://github.com/zalando/postgres-operator</a></td>
<td width="595"><a href="https://github.com/CrunchyData/postgres-operator">https://github.com/CrunchyData/postgres-operator</a></td>
</tr>
</tbody>
</table>
<h3>機能一覧</h3>
<table width="1293">
<tbody>
<tr>
<td width="324"></td>
<td width="484"><b>Zalando</b></td>
<td width="484"><b>Crunchy</b></td>
</tr>
<tr>
<td width="324"><b>自動デプロイ</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>CLI</b></td>
<td width="484">×</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>GUI</b></td>
<td width="484">〇</td>
<td width="484">×</td>
</tr>
<tr>
<td width="324"><b>バックアップ</b></td>
<td width="484">〇   ※S3対応</td>
<td width="484">〇   ※S3対応</td>
</tr>
<tr>
<td width="324"><b>リストア</b></td>
<td width="484">△    ※手動リストアが必要</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>PITR</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>自動</b><b>フェイルオーバ・フェイルバック</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>Multi-Kubernetes </b><b>クラスタ</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>Multi-Zone</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>スケーリング</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>自動アップグレード</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>ローリングアップデート</b></td>
<td width="484">〇　※バージョンアップに伴う停止時間なし</td>
<td width="484">×　※バージョンアップに伴う停止時間あり</td>
</tr>
<tr>
<td width="324"><b>コネクションプーリング</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>監視</b></td>
<td width="484">×</td>
<td width="484">〇</td>
</tr>
<tr>
<td width="324"><b>ボリュームサイズ</b><b>拡張</b></td>
<td width="484">〇</td>
<td width="484">〇</td>
</tr>
</tbody>
</table>
<h3>それぞれの特長</h3>
<p>ZalandoもCrunchyも多くの基本的な機能は共通しており、PostgreSQLクラスタに求められる機能は一通り用意されています。</p>
<p>実績の面では、Zalandoは自社のECサイトで実際に数年運用されている実績があります。CrunchyはPostgreSQLの専門家が開発しているという強みがあります。</p>
<p>Zalandoの基本的にKubernetesの標準的な機能を用いて各種操作を行います。Kubernetesの操作に慣れており、設定追加や変更内容を履歴として残すことを重視するのであればZalandoを選択するメリットがあります。また、ZalandoはGUI(Webインタフェース)が同梱されており、ブラウザから管理を行えます。対してCrunchyは専用の管理コマンドが用意されており、操作が容易で効率的というメリットがあります。</p>
<p>Zalandoはローリングアップデートによりダウンタイムなしでマイナーバージョンアップを行えるメリットもあります。対してCrunchyはアップデート時にある程度のダウンタイムが発生します。</p>
<p>Zalandoは監視などの補助的な機能は標準では用意されておらず、用意されている枠組みを使用してユーザーがある程度作り込みを行う必要があります。対してCrunchyはpgAdmin、ログ解析、監視などの便利な機能が標準で含まれていいるため、導入コストは低くなります。</p>
<h2>おわりに</h2>
<p>本記事では、Kubernetes上でPostgreSQLを運用するメリット、PostgreSQL Operatorの概要と活用例、ZalandoとCrunchyそれぞれの特長について説明しました。</p>
<p>Kubernetes上のアプリケーションでDBを使用する場合や、多数のDBクラスタを迅速に構築したい場合など、PostgreSQL Operatorは様々な活用方法が想定できます。</p>
<p>ZalandoもCrunchyも発展途上のソフトウェアですが、既に多数の機能が実装されており、今後の発展も期待が持てます。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/pgsql-mainte/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-pgsql" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、PostgreSQL/Pgpool-II のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>RHEL/CentOS 8.xへのZabbixのインストール</title>
		<link>https://www.sraoss.co.jp/tech-blog/zabbix/rhel-centos-8/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Mon, 17 Feb 2020 05:30:35 +0000</pubDate>
				<category><![CDATA[Zabbix]]></category>
		<category><![CDATA[OSS]]></category>
		<category><![CDATA[Zabbix 4.4]]></category>
		<category><![CDATA[インストール]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=5417</guid>

					<description><![CDATA[本記事では RHEL 8.x および CentOS 8.x への Zabbix 4.4 のインストールについて解説します。Zabbix公式リポジトリでRHEL/CentOS 8.x向けパッケージが提供されていますが、イン ...]]></description>
										<content:encoded><![CDATA[<p>本記事では RHEL 8.x および CentOS 8.x への Zabbix 4.4 のインストールについて解説します。Zabbix公式リポジトリでRHEL/CentOS 8.x向けパッケージが提供されていますが、インストール時に注意が必要となる点がいくつかあります。基本的にCentOS 8.1環境を使用して説明しますが、 RHEL 8.x で注意が必要な点については補足事項として記載します。</p>
<p><span id="more-5417"></span></p>
<h2>1. 構成</h2>
<p>本記事では以下の構成でインストールを行います。</p>
<ul>
<li>CentOS 8.1 (1911)</li>
<li>Zabbix 4.4.5</li>
<li>Apache httpd 2.4.37 (OS同梱パッケージ)</li>
<li>PostgreSQL 10.6 (OS同梱パッケージ)</li>
<li>ZabbixJavaGateway (JMX監視モジュール)</li>
<li>SNMPTT (SNMPTRAP監視モジュール) ※</li>
</ul>
<p>※ SNMPTT は RHEL/CentOS 8向けパッケージが提供されていないため、 RHEL 7向けパッケージを流用します。</p>
<h2>2. 構築の流れ</h2>
<p>本記事ではRPMパッケージを使用して、以下の手順でインストールを行います。</p>
<ol>
<li>パッケージのインストール</li>
<li>データベース作成</li>
<li>設定ファイルの編集</li>
<li>Zabbixサーバ、エージェント、その他サービスの起動</li>
<li>Webフロントエンドから初期設定</li>
</ol>
<h2>3. インストール前の準備</h2>
<p>SELinuxが有効になっている場合はdisabledもしくはpermissiveにします。また、firewalldの設定でZabbixサーバへの80、10051番ポートへのアクセスを許可しておきます。</p>
<h2>4. パッケージのインストール</h2>
<p>Zabbix本体および依存パッケージを各RPMリポジトリからyumコマンドでインストールします。本記事では以下のリポジトリを使用します。</p>
<ul>
<li><a href="https://repo.zabbix.com/">repo.zabbix.com (Zabbix公式リポジトリ)</a></li>
<li><a href="https://fedoraproject.org/wiki/EPEL/ja">EPEL (RHEL向け拡張パッケージ)</a></li>
</ul>
<h3>4.1 PostgreSQL のインストール</h3>
<p>OSに標準で含まれるPostgreSQL 10.6をインストールします。</p>
<pre># dnf -y install postgresql postgresql-server</pre>
<h3>4.2 Zabbix のインストール</h3>
<p>Zabbixサーバ、Webフロントエンド、Zabbixエージェント、ZabbixJavaGatewayをインストールします。</p>
<p>なお、RHEL/CentOS 8.1ではzabbix-server-pgsqlパッケージが依存しているlibssh2パッケージがリポジトリから削除されているため、インストールに失敗します。このため、libssh2のみRHEL/CentOS 8.0のリポジトリからrpmをインストールしておく必要があります。</p>
<pre># rpm -Uvh http://mirror.centos.org/centos/8.0.1905/AppStream/x86_64/os/Packages/libssh2-1.8.0-8.module_el8.0.0+189+f9babebb.1.x86_64.rpm
# rpm -Uvh https://repo.zabbix.com/zabbix/4.4/rhel/8/x86_64/zabbix-release-4.4-1.el8.noarch.rpm
# dnf clean all
# dnf -y install zabbix-server-pgsql zabbix-web-pgsql zabbix-web-japanese zabbix-apache-conf zabbix-agent
# dnf -y install zabbix-java-gateway</pre>
<h3>4.3 SNMPTT のインストール</h3>
<p>RHEL/CentOS 7.x までの場合はEPELリポジトリのSNMPTTパッケージを利用していました。しかし、現時点では RHEL/CentOS 8 用 EPEL リポジトリには SNMPTT パッケージは含まれていません。このため、暫定的に RHEL/CentOS 7.x 向けの SNMPTT パッケージを使用してインストールを行います。</p>
<p>また、RHEL/CentOS 8からnet-snmp-perlパッケージがリポジトリから削除されたため、net-snmp-perlを利用する機能は使用できないためご注意ください(※必要な場合は net-snmp の SRPM パッケージから rpm をビルドすることが可能です)。</p>
<p>最初にRHEL/CentOS 8向けEPELリポジトリを有効にします。</p>
<pre># rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm</pre>
<p>CentOSのPowerToolsリポジトリに含まれるperl-Digest-SHA1およびperl-IO-stringyが必要となるため、PowerToolsリポジトリを有効にしてsnmpttパッケージのインストールを行います。</p>
<pre># dnf --enablerepo=PowerTools -y install https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/s/snmptt-1.4-0.9.beta2.el7.noarch.rpm</pre>
<p>(注) RHEL 8.xの場合は上記のパッケージはCodeReady Linux Builder for x86_64 (codeready-builder-for-rhel-8-x86_64-rpms)リポジトリに含まれるため、以下のようにしてリポジトリを有効にしてください。</p>
<pre># subscription-manager repos --enable=codeready-builder-for-rhel-8-x86_64-rpms
# dnf -y install https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/s/snmptt-1.4-0.9.beta2.el7.noarch.rpm</pre>
<p>あわせてnet-snmp、net-snmp-utilsおよびperl-Sys-Syslogパッケージをインストールします。</p>
<pre># dnf -y install net-snmp net-snmp-utils perl-Sys-Syslog</pre>
<h2>5. データベースの作成</h2>
<p>データベースの初期化を行い、Zabbixのデータベースを作成します。</p>
<pre># PGSETUP_INITDB_OPTIONS="-E utf8 --no-locale" /usr/bin/postgresql-setup --initdb
* Initializing database in '/var/lib/pgsql/data'
* Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log</pre>
<p>pg_hba.confを編集し、TCP接続時のパスワード認証を有効にします。</p>
<pre># vi /var/lib/pgsql/data/pg_hba.conf
# IPv4 local connections:
#host    all             all             127.0.0.1/32            ident
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
#host    all             all             ::1/128                 ident
host    all             all             ::1/128                 md5</pre>
<p>PostgreSQLを起動し、ユーザおよびデータベースを作成します。</p>
<pre># systemctl start postgresql

# sudo -u postgres createuser --pwprompt zabbix
Enter password for new role:
Enter it again:
# sudo -u postgres createdb -O zabbix zabbix

# zcat /usr/share/doc/zabbix-server-pgsql*/create.sql.gz | sudo -u zabbix psql zabbix</pre>
<h2>6. Zabbixサーバ設定</h2>
<p>ZabbixサーバのDB設定、ZabbixJavaGateway、Zabbixエージェント、フロントエンドのタイムゾーン、およびSNMPTTの設定を行います。</p>
<pre># vi /etc/zabbix/zabbix_server.conf
DBName=zabbix
DBUser=zabbix
DBPassword=&lt;パスワード&gt;

JavaGateway=127.0.0.1
JavaGatewayPort=10052
StartJavaPollers=1

SNMPTrapperFile=/var/log/snmptt/snmptt.log
StartSNMPTrapper=1</pre>
<pre># vi /etc/zabbix/zabbix_agentd.conf
Server=127.0.0.1
ServerActive=127.0.0.1
Hostname=(Zabbixエージェントのホスト名) ※Zabbixサーバ上のホストの設定と一致させる必要があります</pre>
<pre># vi /etc/php-fpm.d/zabbix.conf
php_value[date.timezone] = Asia/Tokyo</pre>
<h3>6.1 SNMPTTの設定</h3>
<p>snmptrapdの起動オプションを変更します。</p>
<pre># vi /etc/sysconfig/snmptrapd
OPTIONS="-m +ALL -Lsd -On"</pre>
<p>snmptrapd.confに、受信したSNMPトラップをSNMPTTに送る設定を追加します。</p>
<pre># vi /etc/snmp/snmptrapd.conf
authCommunity   log,execute,net public
traphandle default /usr/sbin/snmptthandler</pre>
<p>snmptthandler-embeddedを使用する場合はtraphandleの代わりに以下を追加します。なお、snmptthandler-embeddedを使用する場合はnet-snmp-perlが必要になります。</p>
<pre>perl do "/usr/share/snmptt/snmptthandler-embedded"</pre>
<p>snmptt.iniを以下のように変更します。</p>
<pre># vi /etc/snmp/snmptt.ini
#mode = standalone
mode = daemon

#net_snmp_perl_enable = 0
(net-snmp-perlを使用する場合のみ) net_snmp_perl_enable = 1

#net_snmp_perl_best_guess = 0
(net-snmp-perlを使用する場合のみ) net_snmp_perl_best_guess = 2

#sleep = 5
sleep = 1</pre>
<p>snmptt.conf に下記を記述すると、すべてのSNMPトラップを「Unknown trap」として受け取り、snmptt.logファイルに出力します。実際には監視したいトラップのOIDごとに設定を行います。</p>
<pre># vi /etc/snmp/snmptt.conf
EVENT general .* "Unknown trap" Normal
FORMAT ZBXTRAP $aA $ar $*</pre>
<p>SNMPTTおよびsnmptrapdの起動および自動起動を有効にします。</p>
<pre># systemctl enable --now snmptt snmptrapd</pre>
<p>テストトラップを送信し、snmptt.logログファイルにトラップが出力されることを確認します。</p>
<pre># snmptrap -v 2c -c public 127.0.0.1 '' .1.3.6.1.4.1.8072.9999 .1.3.6.1.4.1.8072.9999 s 'Hello'
# cat /var/log/snmptt/snmptt.log
Tue Feb  4 15:43:56 2020 .1.3.6.1.4.1.8072.9999 Normal "Unknown trap" localhost - ZBXTRAP 127.0.0.1 127.0.0.1 Hello</pre>
<h2>7. Zabbixサーバの起動</h2>
<p>Zabbixサーバおよび必要なその他サービスを起動し、同時に自動起動設定も行います。</p>
<pre># systemctl enable --now zabbix-server zabbix-agent zabbix-java-gateway httpd php-fpm
</pre>
<h2>8. Webフロントエンドの設定</h2>
<p>Webブラウザから http://(Zabbixサーバのホスト名orIPアドレス)/zabbix にアクセスし、画面の指示に従って初期設定を行います。アクセスできない場合はSELinuxおよびfirewalldの設定が正しく行われているかを確認してください。</p>
<p><img loading="lazy" decoding="async" class="wp-image-5485 aligncenter" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/Installation-2020-01-08s.png" alt="" width="640" height="387" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/Installation-2020-01-08s.png 864w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/Installation-2020-01-08s-300x182.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/Installation-2020-01-08s-768x465.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/Installation-2020-01-08s-304x184.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/Installation-2020-01-08s-282x171.png 282w" sizes="auto, (max-width: 640px) 100vw, 640px" /></p>
<p>設定完了後表示されるログイン画面で初期管理者ユーザ/パスワード(Admin/zabbix)でログインするとダッシュボード画面が表示されます。</p>
<p>右上のユーザープロファイルアイコンから、UserタブのLanguageを「Japanese (ja_JP)」に変更し、「Update」ボタンをクリックすると表示が日本語に切り替わります。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-5568" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/zabbix44-dashboard-jp.png" alt="" width="1331" height="1241" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/zabbix44-dashboard-jp.png 1331w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/zabbix44-dashboard-jp-300x280.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/zabbix44-dashboard-jp-768x716.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/zabbix44-dashboard-jp-1024x955.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/zabbix44-dashboard-jp-230x214.png 230w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2020/01/zabbix44-dashboard-jp-279x260.png 279w" sizes="auto, (max-width: 1331px) 100vw, 1331px" /></p>
<p>以上でRHEL/CentOS 8.xへのZabbixサーバのインストールは完了です。</p>
<h2>9. おわりに</h2>
<p>今回はRHEL/CentOS 8.xへのZabbixサーバのインストールについて解説しました。RHEL/CentOS 8.xはまだリリースされてから日が浅く、廃止されたパッケージなどもあるため、現時点ではやや手順が煩雑になります。これらの課題は今後のZabbixのリリースで解消していくものと思われます。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Redisモジュールの解説</title>
		<link>https://www.sraoss.co.jp/tech-blog/redis/redis-modules/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Thu, 26 Dec 2019 02:00:16 +0000</pubDate>
				<category><![CDATA[Redis]]></category>
		<category><![CDATA[KVS]]></category>
		<category><![CDATA[OSS]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=5017</guid>

					<description><![CDATA[Redis 4.0で追加されたモジュール機能により、ユーザがRedisの機能を自由に拡張することができます。 今回はRedisのモジュール機能で可能なことの解説、およびRedisのスポンサーであるRedis Labsや他 ...]]></description>
										<content:encoded><![CDATA[<p>Redis 4.0で追加された<a href="https://redis.io/topics/modules-intro">モジュール機能</a>により、ユーザがRedisの機能を自由に拡張することができます。</p>
<p>今回はRedisのモジュール機能で可能なことの解説、およびRedisのスポンサーであるRedis Labsや他のサードパーティにより公開されている様々なモジュールの紹介を行います。</p>
<p><span id="more-5017"></span></p>
<h2>Redisモジュールとは</h2>
<p>Redisモジュールは、Redisに外部モジュールをロードすることで、Redis本体に手を入れることなく機能拡張できる仕組みです。モジュールは通常C/C++で実装されますが、技術的には他の言語でも実装可能です。</p>
<h2>Redisモジュールで可能なこと</h2>
<p>RedisモジュールではRedisに以下のような機能の拡張が可能です。新しいコマンドを呼び出したときに実行する処理をすべてモジュール側で実装することもできますし、Redisの機能を利用して実装することも可能です。</p>
<ul>
<li>新しいコマンドの作成</li>
<li>Redisの機能をモジュールから呼び出す</li>
<li>新しいデータ型の作成</li>
<li>レプリケーション、クラスタにも対応できる (RDB、AOFの永続化処理を実装すればOK)</li>
</ul>
<h2>Redisモジュールのライセンス変更について</h2>
<p>Redisのスポンサー企業であるRedis Labsが開発、提供するモジュールについてライセンスの変更が行われました。</p>
<p>対象は RediSearch, RedisGraph, RedisJSON, RedisML, RedisBloom などで、当初のAGPLから、(2018/8) Apache v2.0 modified with Commons Clause -&gt; (2019/2) Redis Source Available License (RSAL)と2回の変更が行われました。これは大手クラウド業者などがRedisモジュールの機能をそのままサービスとして提供することで利益を得る、いわゆるフリーライドを防ぐ意図があります。</p>
<p>なお、Redis本体のライセンスには変更はありません(引き続き3条項BSDライセンスが適用されます)。他のRSALを適用していないモジュールや、ユーザーが実装するモジュールにも制限はありません。</p>
<h3>RSALの制限事項</h3>
<p>RSALライセンスではソースコードの利用・改変・再配布や、Redisモジュールを使ったサービスや製品の販売は認められています。ただし、以下の開発に使用することは禁止されています。</p>
<ul>
<li>データベース</li>
<li>キャッシュエンジン</li>
<li>ストリーム処理エンジン</li>
<li>検索エンジン</li>
<li>インデックスエンジン</li>
<li>機械学習(ディープラーニング含む)、AIエンジン</li>
<li>RedisのAPIやRedis Modules APIを公開する製品やサービス</li>
</ul>
<h2>Redisモジュールの作り方</h2>
<p>Redisモジュールをビルドするのに必要なものは、Redisの最新版ソースコードに含まれる redismodule.h のみと非常にシンプルです。ライブラリ等依存コンポーネントがないため、手軽に作成することができます。</p>
<p>Redisのソースコードは以下のページからダウンロードできます。通常はStableを使用してください。</p>
<p><a href="https://redis.io/download">https://redis.io/download</a></p>
<h3>サンプルコード</h3>
<p>helloworld.randコマンドを実行するとrand()で生成した乱数を返す単純なモジュールです。</p>
<pre>#include "redismodule.h"
#include &lt;stdlib.h&gt;

int HelloworldRand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    RedisModule_ReplyWithLongLong(ctx, rand());
    return REDISMODULE_OK;
}

int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
    if (RedisModule_Init(ctx, "helloworld", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR)
        return REDISMODULE_ERR;

    if (RedisModule_CreateCommand(ctx, "helloworld.rand", HelloworldRand_RedisCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR)
        return REDISMODULE_ERR;

    return REDISMODULE_OK;
}</pre>
<h3>コンパイル、配置、ロード</h3>
<pre>$ gcc --shared -fPIC helloworld.c -o helloworld.so
$ sudo cp helloworld.so /var/lib/redis/helloworld.so
$ redis-cli module load /var/lib/redis/helloworld.so
(設定ファイルに書く場合は /etc/redis.conf に以下を追加)
loadmodule /var/lib/redis/helloworld.so</pre>
<h3>実行</h3>
<pre>$ redis-cli
127.0.0.1:6379&gt; helloworld.rand
(integer) 855445334
127.0.0.1:6379&gt; helloworld.rand
(integer) 705120217</pre>
<h2>公開中のモジュールの紹介</h2>
<p>ここではRedisモジュールの活用例として、<a href="https://redis.io/modules">Redis Modules</a>のページで公開されているモジュールの中から興味深いものについていくつか紹介します。</p>
<ul>
<li><strong>RediSearch:</strong> 全文検索</li>
<li><strong>RedisAI/RedisML/neural-redis:</strong> 機械学習エンジン</li>
<li><strong>RedisGraph:</strong> グラフDB</li>
</ul>
<h3>RediSearch</h3>
<p><a href="https://github.com/RediSearch/RediSearch.git">RediSearch</a>はRedisに全文検索エンジンを追加するモジュールです。多言語に対応しており、中国語には対応していますが日本語には残念ながら未対応です(工夫により対応することは可能です)。RediSearchはRedis Labs社によりRSALライセンスで配布されています。</p>
<p>RediSearchのビルド手順は以下のようになります(RHEL7系の場合)。</p>
<pre>$ sudo yum install cmake3 --enablerepo=epel
$ git clone https://github.com/RediSearch/RediSearch.git
$ cd RediSearch; mkdir build; cd build
$ cmake3 .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
$ make
$ sudo cp redisearch.so /var/lib/redis/
$ redis-cli module load "/var/lib/redis/redisearch.so"</pre>
<p>簡単な使い方を以下に示します。</p>
<pre>[スキーマを作成]
127.0.0.1:6379&gt; ft.create myidx schema title text weight 5.0 body text url text

[ドキュメントを追加]
127.0.0.1:6379&gt; ft.add myidx doc1 1.0 fields title "Hello World" body "This is a test document." url "http://localhost/"

[検索]
127.0.0.1:6379&gt; ft.search myidx "test" limit 0 10
1) (integer) 1
2) "doc1"
3) 1) title
2) "Hello World"
3) body
4) "This is a test document."
5) url
6) "http://localhost/"</pre>
<p>あらかじめ分かち書きを行っておくことで日本語も一応使うことが出来ます。</p>
<pre>$ redis-cli --raw ※日本語UTF-8文字列をエスケープせずそのまま出力するため--rawを付加
127.0.0.1:6379&gt; ft.create jpidx schema title text weight 5.0 body text title.orig text weight 0.0 body.orig text weight 0.0
127.0.0.1:6379&gt; ft.add jpidx d2 1.0 fields title "日本語 の テスト" body "これは 試験 用 の 文章 です 。" title.orig "日本語のテスト" body.orig "これは試験用の文章です。"
127.0.0.1:6379&gt; ft.search jpidx 日本語
1
d2
title
日本語 の テスト
body
これは 試験 用 の 文章 です 。
body.orig
これは試験用の文章です。
title.orig
日本語のテスト</pre>
<h3>neural-redis</h3>
<p><a href="https://github.com/antirez/neural-redis">neural-redis</a>はRedisにニューラルネットワークによる機械学習エンジンを追加するモジュールです。以下のような特徴があります。</p>
<ul>
<li>非常にシンプルなAPI</li>
<li>他のライブラリに依存せず単体で動作</li>
<li>データ自動正規化</li>
<li>別スレッドによるバックグラウンド処理</li>
<li>過学習検知付き自動トレーニング</li>
<li>Salvatore Sanfilippo (Redis開発者)が開発</li>
<li>3条項BSDライセンス</li>
</ul>
<p>他の機械学習・ディープラーニングエンジンとして、Redis Labs社により公開されている<a href="https://github.com/RedisLabsModules/redisml">RedisML</a>および<a href="https://github.com/RedisAI/RedisAI">RedisAI</a>があります。</p>
<p>neural-redisのビルド手順は以下のようになります。</p>
<pre>$ git clone https://github.com/antirez/neural-redis
$ cd neural-redis/
$ make sse
$ sudo cp neuralredis.so /var/lib/redis/
$ redis-cli module load "/var/lib/redis/neuralredis.so"</pre>
<h4>neural-redis (1) 回帰分析</h4>
<p>入力データから数値の予測を行う問題の例として、足し算の答えの予測 (a + b = c)を行います。</p>
<h5>ニューラルネットワークの作成</h5>
<pre>$ redis-cli
127.0.0.1:6379&gt; NR.CREATE net REGRESSOR 2 3 -&gt; 1 NORMALIZE DATASET 50 TEST 10
(integer) 13</pre>
<h5>学習データを投入</h5>
<pre>127.0.0.1:6379&gt; NR.OBSERVE net 1 2 -&gt; 3
127.0.0.1:6379&gt; NR.OBSERVE net 4 5 -&gt; 9
127.0.0.1:6379&gt; NR.OBSERVE net 3 4 -&gt; 7
127.0.0.1:6379&gt; NR.OBSERVE net 1 1 -&gt; 2
127.0.0.1:6379&gt; NR.OBSERVE net 2 2 -&gt; 4
127.0.0.1:6379&gt; NR.OBSERVE net 0 9 -&gt; 9
127.0.0.1:6379&gt; NR.OBSERVE net 7 5 -&gt; 12
127.0.0.1:6379&gt; NR.OBSERVE net 3 1 -&gt; 4
127.0.0.1:6379&gt; NR.OBSERVE net 5 6 -&gt; 11</pre>
<h5>トレーニング開始</h5>
<pre>127.0.0.1:6379&gt; NR.TRAIN net AUTOSTOP
Training has started</pre>
<h5>トレーニング結果のテスト</h5>
<p>比較的想定に近い結果が出ていることがわかります。</p>
<pre>127.0.0.1:6379&gt; NR.RUN net 1 1
1) "2.0505485534667969"
127.0.0.1:6379&gt; NR.RUN net 4 6
1) "10.419864654541016"
127.0.0.1:6379&gt; NR.RUN net 2 3
1) "4.8927350044250488"</pre>
<h4>neural-redis (2) 分類</h4>
<p>入力データをグループ分けする問題の例として、neural-redisにサンプルとして付属しているタイタニック号の乗客の生存予測を行います。</p>
<h5>モジュールに同梱されているサンプル</h5>
<ul>
<li>入力パラメータ: 乗客の各種属性(チケットクラス、性別、年齢、兄弟・親子の乗船数、チケット料金)</li>
<li>分類ラベル: 生存 or 死亡</li>
</ul>
<h5>付属のRubyスクリプトで学習データ(CSV形式)の投入とトレーニング</h5>
<pre>$ cd neural-redis/examples
$ ruby titanic.rb
Before training
185 prediction errors on 290 items
Still training...
After training
47 prediction errors on 290 items</pre>
<h5>トレーニング結果のテスト</h5>
<p>ファーストクラス、女性、30歳、兄弟・親子なしの場合、95%の確率で生存という結果になりました</p>
<pre>$ redis-cli
127.0.0.1:6379&gt; NR.RUN mynet 1 0 0 0 1 30 0 0 200
1) "0.066139459609985352"
2) "0.94962334632873535"</pre>
<p>年齢を70歳に上げた場合、95%から92.5%に減少しました。</p>
<pre>127.0.0.1:6379&gt; NR.RUN mynet 1 0 0 0 1 70 0 0 200
1) "0.08922017365694046"
2) "0.925819993019104"</pre>
<p>70歳、サードクラス、格安チケットのように条件を悪くした場合、生存率が32%と大幅に減少しました。</p>
<pre>127.0.0.1:6379&gt; NR.RUN mynet 0 0 1 0 1 70 0 0 20
1) "0.6508185863494873"
2) "0.32001861929893494"</pre>
<p>より高度な使い方は<a href="https://github.com/antirez/neural-redis">neural-redis</a>のgithubページを参照してください。</p>
<h3>RedisGraph</h3>
<p><a href="https://github.com/RedisGraph/RedisGraph">RedisGraph</a>はRedisにグラフDB機能を追加するモジュールです。グラフDBはグラフ構造に特化したDBのことです。グラフDBとしてメジャーな<a href="https://neo4j.com/">Neo4j</a>のグラフクエリー言語であるCypherを採用しており、Neo4jの利用経験があればすぐに使うことができます。<br />
RedisGraphはRedis Labs社によりRSALライセンスで配布されています。</p>
<p>RedisGraphのビルドはやや複雑なため、ここではDockerイメージを使用して実行します。</p>
<pre># docker run -p 6379:6379 -it --rm redislabs/redisgraph</pre>
<p>RedisGraphではGRAPH.QUERYコマンドに対してスキーマ名とCypherクエリー文字列を指定して使用します。簡単な使い方を以下に示します。</p>
<h4>グラフを作成</h4>
<p>例として人同士の関係をグラフとして作成してみます。以下はJohnの友人はFred、Lisaの友人はMaryという関係をグラフ化したものです。</p>
<pre>$ redis-cli
127.0.0.1:6379&gt; GRAPH.QUERY People
"CREATE (:Person {name:'John'})-[:friend]-&gt;(:Person {name:'Fred'}),
(:Person {name:'Lisa'})-[:friend]-&gt;(:Person {name:'Mary'})"
1) 1) "Labels added: 1"
2) "Nodes created: 4"
3) "Properties set: 4"
4) "Relationships created: 2"
5) "Query internal execution time: 3.208423 milliseconds"</pre>
<h4>クエリ実行</h4>
<p>上記で登録した人同士の関係のグラフから、Fred の友人を検索してみます。</p>
<pre>127.0.0.1:6379&gt; GRAPH.QUERY People
"MATCH (p1:Person)-[:friend]-&gt;(p2:Person)
WHERE p2.name = 'Fred'
RETURN p1.name, p2.name"
1) 1) "p1.name"
2) "p2.name"
2) 1) 1) "John"
2) "Fred"
3) 1) "Query internal execution time: 0.326652 milliseconds"</pre>
<p>条件にマッチした数をカウントすることもできます。以下ではMaryの友人の数をカウントしています。</p>
<pre>127.0.0.1:6379&gt; GRAPH.QUERY People
"MATCH (p1:Person)-[:friend]-&gt;(p2:Person {name:'Mary'})
RETURN count(p1)"
1) 1) "count(p1)"
2) 1) 1) (integer) 1
3) 1) "Query internal execution time: 0.290916 milliseconds"</pre>
<h2>まとめ</h2>
<p>今回はRedisモジュールについて紹介しました。RedisモジュールによりユーザーがRedisに対して自由に機能拡張を行うことができます。HA機能を含むRedisの既存の機能を利用してRedisモジュールを実装することができるため、Redisコア機能の恩恵が得られます。</p>
<p>現在既に様々な高機能なRedisモジュールが提供されており、今後も新しいRedisモジュールの登場が期待できます。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Zabbix 4.4の紹介</title>
		<link>https://www.sraoss.co.jp/tech-blog/zabbix/zabbix44-newfeature/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Wed, 16 Oct 2019 01:30:21 +0000</pubDate>
				<category><![CDATA[Zabbix]]></category>
		<category><![CDATA[OSS]]></category>
		<category><![CDATA[Zabbix 4.4]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=4262</guid>

					<description><![CDATA[本記事では、2019/10/7にリリースされた Zabbix 4.4で追加された機能や変更点について解説します。 Zabbix 4.4の変更点は以下のページに記載されています。 5 What&#8217;s new in ...]]></description>
										<content:encoded><![CDATA[<p>本記事では、2019/10/7にリリースされた Zabbix 4.4で追加された機能や変更点について解説します。</p>
<p>Zabbix 4.4の変更点は以下のページに記載されています。</p>
<p><a href="https://www.zabbix.com/documentation/4.4/manual/introduction/whatsnew440">5 What&#8217;s new in Zabbix 4.4.0</a><br />
<a href="https://www.zabbix.com/rn/rn4.4.0">Release Notes for Zabbix 4.4.0</a></p>
<p>Zabbix 4.4はポイントリリースとなり、サポート期間が短いため、実運用ではLTSバージョンの利用を推奨します。</p>
<p><span id="more-4262"></span></p>
<p>Zabbix 4.4の主な変更点を以下に挙げます。</p>
<h3>Zabbix agent 2</h3>
<p>Zabbix agent 2と呼ばれる第二世代のエージェントが実装されました。Zabbix agent 2は Go 言語で実装されており、以下の特長があります。</p>
<ul>
<li>TCP接続数の削減</li>
<li>チェックの並列性の向上</li>
<li>プラグインによる拡張が容易</li>
<li>以前の Zabbix エージェントをそのまま置き換え可能</li>
</ul>
<h3>Webhook 通知</h3>
<p>Webhook メディアタイプが追加され、 JavaScript によりアラートの拡張が可能になりました。これにより外部スクリプトを使用せずZabbix内で完結したWebベースのアラートの処理が行えます。</p>
<p>具体的な例としては、Webhook通知を使用してSlackへの通知を行うことができます(以下のマニュアルのサンプルを参照)。</p>
<p><a href="https://www.zabbix.com/documentation/4.4/manual/config/notifications/media/webhook">4 Webhook</a></p>
<h3>障害の監視データの表示</h3>
<p>障害ビューの監視データの表示内容をトリガーの設定でカスタマイズできるようになりました。これにより障害発生時点の監視データではなく最新値を表示させることなどが可能です。</p>
<h3>ローレベルディスカバリ</h3>
<p>ローレベルディスカバリについて新たに以下が実装されました。</p>
<ul>
<li>ブロックデバイスのローレベルディスカバリ (vfs.dev.discovery)</li>
<li>systemd サービスのローレベルディスカバリ (systemd.unit.discovery) (要 Zabbix agent 2)</li>
<li>JMX MBeanディスカバリの非 ASCII 文字対応 (jmx.get)</li>
<li>WMIディスカバリのためのアイテムの追加 (wmi.getall)</li>
</ul>
<h3>安全なエージェントの自動登録</h3>
<p>PSK認証およびTLS暗号化された接続を使用した安全なエージェントの自動登録が可能になりました。</p>
<h3>保存前処理</h3>
<p>保存前処理について新たに以下が実装されました。</p>
<ul>
<li>JSON、XML、正規表現によるエラーチェックのカスタムエラー処理を追加</li>
<li>LLD に XML 関係(XML XPath、XMLエラーチェック)の前処理オプションを追加</li>
</ul>
<h3>新規テンプレート</h3>
<p>以下の新規テンプレートが追加されました。</p>
<ul>
<li>Nginx</li>
<li>Apache</li>
<li>RabbitMQ</li>
<li>MySQL/MariaDB</li>
<li>PostgreSQL</li>
</ul>
<p>PostgreSQLのテンプレート(Template DB PostgreSQL)はUserParameterにより実装されています。詳細については以下を参照ください。</p>
<p><a href="https://www.zabbix.com/documentation/4.4/manual/config/templates_out_of_the_box/requirements/postgresql">Requirements for PostgreSQL template</a></p>
<h3>フロントエンド</h3>
<p>ダッシュボードのウィジェットに様々な改良が行われました。</p>
<h4>棒グラフ追加</h4>
<p>グラフウィジェットで棒グラフ表示が可能になりました。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4296" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-bargraph.png" alt="" width="711" height="349" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-bargraph.png 711w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-bargraph-300x147.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-bargraph-304x149.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-bargraph-282x138.png 282w" sizes="auto, (max-width: 711px) 100vw, 711px" /></p>
<h4>グラフ上の集約関数</h4>
<p>ダッシュボードのグラフウィジェット上でmin、max、avgなどの集約関数を使用してデータを表示できるようになりました。これにより、累計チェックアイテムを作成することなく集約されたグラフを表示することが可能です。</p>
<p><a href="https://www.zabbix.com/documentation/4.4/manual/config/visualisation/graphs/aggregate">4 Aggregation in graphs</a></p>
<h4>深刻度ごとの障害数ウィジェットの拡張</h4>
<p>深刻度ごとの障害数ウィジェットでホストグループ全体の障害数の合計をまとめて表示できるようになりました。縦横レイアウトが可能です。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4280" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-prob-by-severity3.png" alt="" width="711" height="279" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-prob-by-severity3.png 711w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-prob-by-severity3-300x118.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-prob-by-severity3-304x119.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-prob-by-severity3-282x111.png 282w" sizes="auto, (max-width: 711px) 100vw, 711px" /></p>
<h4>Host availability ウィジェットの追加</h4>
<p>ホストの稼働状況を集約して表示できるウィジェットが追加されました。インタフェースのタイプごとに稼働状況を表示することが可能です。縦横レイアウトが可能です。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4283" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-host-availability2.png" alt="" width="474" height="197" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-host-availability2.png 474w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-host-availability2-300x125.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-host-availability2-304x126.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-host-availability2-282x117.png 282w" sizes="auto, (max-width: 474px) 100vw, 474px" /></p>
<h4>グラフプロトタイプウィジェットの追加</h4>
<p>LLDによりグラフプロトタイプから生成されたグラフを格子状に表示できるウィジェットが追加されました。</p>
<h4>最新データのアイテムの説明アイコンの追加</h4>
<p>[監視データ] &#8211; [最新データ]の各アイテムに説明を表示するアイコンが追加されました。</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4319" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-items-description.png" alt="" width="807" height="404" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-items-description.png 807w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-items-description-300x150.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-items-description-768x384.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-items-description-304x152.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/10/zabbix44-items-description-282x141.png 282w" sizes="auto, (max-width: 807px) 100vw, 807px" /></p>
<h3>性能</h3>
<p>アイテムの設定を格納するitemsテーブルのうちリアルタイムに更新されるフィールド(lastlogsize, state, mtime, error)が item_rtdata テーブルに分割されました。これによりZabbixサーバプロセスとフロントエンドからデータベースにアクセスする際の望ましくないロックが回避されるようになりました。</p>
<h3>その他</h3>
<p>その他以下のような改良、機能追加、変更が行われました。</p>
<ul>
<li><a href="https://www.timescale.com/">TimescaleDB</a> (PostgreSQLの時系列データ拡張)の正式サポート</li>
<li>エージェントの自動登録がDNS 名で可能</li>
<li>ホストディスカバリでホスト名の長さを64文字から128文字に拡張</li>
<li>データベース監視で複数行・列の返却が可能</li>
<li>依存アイテムの上限が999から29999に上昇</li>
<li>Web監視およびHTTPエージェントでKerberos 認証のサポート</li>
<li>メディアタイプのエクスポート・インポートが可能</li>
<li>Jabber、Ez Textingメディアタイプの削除</li>
<li>トリガーURLで{EVENT.ID}マクロが利用可能</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Redisストリームについて</title>
		<link>https://www.sraoss.co.jp/tech-blog/redis/redis-streams/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Mon, 02 Sep 2019 04:00:33 +0000</pubDate>
				<category><![CDATA[Redis]]></category>
		<category><![CDATA[KVS]]></category>
		<category><![CDATA[OSS]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=3750</guid>

					<description><![CDATA[RedisストリームはRedis 5で新しく追加されたデータ型です。 Apache Kafka に類似したメッセージ処理のためのパワフルな機能を持っており、様々な応用が可能です。 既存の類似の機能 最初にRedisのメッ ...]]></description>
										<content:encoded><![CDATA[<p><a href="https://redis.io/topics/streams-intro">Redisストリーム</a>はRedis 5で新しく追加されたデータ型です。 <a href="https://kafka.apache.org/">Apache Kafka</a> に類似したメッセージ処理のためのパワフルな機能を持っており、様々な応用が可能です。</p>
<p><span id="more-3750"></span></p>
<h2>既存の類似の機能</h2>
<p>最初にRedisのメッセージ処理に適した既存の機能をいくつか紹介します。</p>
<h3>Pub/Sub</h3>
<p>Redisは<a href="https://redis.io/topics/pubsub">Pub/Sub</a>メッセージング機能を提供しています。SUBSCRIBE および PUBLISH コマンドにより、 Publisher(発行者)が送信したメッセージを複数の Subscriber(購読者)が受信することができます。PublisherはSubscriberを知っている必要がなく、メッセージを受け取れないPublisherがあってもSubscriberは影響を受けません。ただし、メッセージは保存されないため、SUBSCRIBEしていない期間のメッセージを受け取ることはできません。</p>
<figure id="attachment_3761" aria-describedby="caption-attachment-3761" style="width: 500px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="wp-image-3761" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-pubsub-1024x416.png" alt="" width="500" height="203" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-pubsub-1024x416.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-pubsub-300x122.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-pubsub-768x312.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-pubsub-304x123.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-pubsub-282x115.png 282w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-pubsub.png 1332w" sizes="auto, (max-width: 500px) 100vw, 500px" /><figcaption id="caption-attachment-3761" class="wp-caption-text">Pub/Subモデル</figcaption></figure>
<h3>Blocked list</h3>
<p>Redisのリスト型はメッセージキューとして使うことができ、 <a href="https://redis.io/commands/BLPOP">BLPOP</a> および BRPOP コマンドにより、リストの先頭もしくは末尾からデータ(メッセージ)の到着を待って受信することができます。複数のクライアントが同時に受信を待つことができますが、1つのメッセージを受け取った時点でそのメッセージは削除されるので、1つのメッセージを受け取れるのは1つのクライアントのみとなります。</p>
<figure id="attachment_3777" aria-describedby="caption-attachment-3777" style="width: 600px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="wp-image-3777" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-blist-300x64.png" alt="" width="600" height="129" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-blist-300x64.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-blist-768x165.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-blist-1024x219.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-blist-304x65.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-blist-282x60.png 282w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-blist.png 1307w" sizes="auto, (max-width: 600px) 100vw, 600px" /><figcaption id="caption-attachment-3777" class="wp-caption-text">Blocked list</figcaption></figure>
<h2>ストリームの特徴</h2>
<p>Redisストリームは前述のPub/SubおよびBlocked listに対して大幅に強化された機能をもちます。</p>
<p>Redisストリームは以下のような特徴があります。</p>
<ul>
<li>データを時系列で持つ追記型データ構造</li>
<li>各データは任意の複数のフィールドを持つことができる</li>
<li>データを取得しても過去のデータを残せる</li>
<li>時間の範囲を指定して複数のデータを読み出せる</li>
<li>コンシューマグループの概念によりクライアントをグループ化して協調動作できる</li>
</ul>
<figure id="attachment_3782" aria-describedby="caption-attachment-3782" style="width: 720px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="wp-image-3782" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-streams-1024x711.png" alt="" width="720" height="500" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-streams-1024x711.png 1024w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-streams-300x208.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-streams-768x533.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-streams-304x211.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-streams-282x196.png 282w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/08/redis-streams.png 1376w" sizes="auto, (max-width: 720px) 100vw, 720px" /><figcaption id="caption-attachment-3782" class="wp-caption-text">Redisストリーム</figcaption></figure>
<h2>ストリームのデータ構造</h2>
<p>Redisストリームのデータ構造自体は比較的シンプルです。</p>
<p>Redisストリームは追記専用のデータ構造です。各エントリは固有のIDを持ちます。IDは単調増加し、データ追加時にIDを指定しない場合は現在時刻から「&lt;タイムスタンプ&gt;-&lt;連番&gt;」の形式で自動生成されます。1つのエントリは任意の数のフィールドと値のペアで構成されます。</p>
<h2>使用例</h2>
<h3>監視データをストリームに保存することを想定した場合の例</h3>
<p>一定時間ごとに監視ツールで計測した監視データを時系列でストリームに保存するという用途を想定します。ここではストリームは単に時系列のデータ構造として使用し、1レコードにホストID、監視項目とその値を保存するものとします。</p>
<h4>データを追加</h4>
<p><a href="https://redis.io/commands/xadd">XADD</a>コマンドでストリーム名、ID、フィールド名と値を指定してデータを追加します。IDに「*」を指定するとIDを自動生成します。</p>
<pre>&gt; XADD history * hostid 1234 cpu.util 1.2
"1565915608548-0" (←自動生成されたID)
&gt; XADD history * hostid 1350 mem.used 65.3
"1565915613858-0" (←自動生成されたID)
...</pre>
<h4>全範囲のメッセージを取得</h4>
<p><a href="https://redis.io/commands/xrange">XRANGE</a>コマンドは指定した範囲のIDのデータを取得します。「-」は最小のID、「+」は最大のIDを意味するので、以下のコマンドはすべてのデータが取得されます。</p>
<pre>&gt; XRANGE history - +
1) 1) "1565915608548-0"
   2) 1) "hostid"
      2) "1234"
      3) "cpu.util"
      4) "1.2"
2) 1) "1565915613858-0"
   2) 1) "hostid"
      2) "1350"
      3) "mem.used"
      4) "65.3"</pre>
<h4>最初から1つ分のメッセージを取得</h4>
<p><a href="https://redis.io/commands/xread">XREAD</a>コマンドは指定したIDより大きいIDを持つデータを取得します。ID 0 (0-0)は最小のIDを意味するので、ストリームの最初からデータを取得することになります。COUNTオプションで一回で取得するデータの数を指定できます。</p>
<pre>&gt; XREAD COUNT 1 STREAMS history 0
1) 1) "1565915608548-0"
   2) 1) "hostid"
      2) "1234"
      3) "cpu.util"
      4) "1.2"</pre>
<h3>簡易チャットの例</h3>
<p>Slackのような複数チャンネルを持ち、過去の履歴も含めて参照可能なチャットシステムを簡易的に再現してみます。</p>
<h4>チャンネル作成、発言</h4>
<p>XADDコマンドでチャンネル名のストリームにメッセージを追加します。ストリームが存在しない場合は自動的に作成されます。格納するデータはメッセージ本体と発言者とします。</p>
<pre>&gt; XADD #channel * msg "channel #channel created."
"1565932257598-0"
&gt; XADD #channel * msg "こんにちは" user "Taro"
"1565932327972-0"
&gt; XADD #channel * msg "@Taro こんにちは!" user "Hanako"
"1565932387775-0"</pre>
<h4>新規に参加したユーザがチャンネルの最初からメッセージを取得</h4>
<p>XREADコマンドでチャンネルの最初からすべてのメッセージを取得します。</p>
<pre>&gt; XREAD STREAMS #channel 0
1) 1) "#channel"
   2) 1) 1) "1565932257598-0"
         2) 1) "msg"
            2) "channel #channel created."
      2) 1) "1565932327972-0"
         2) 1) "msg"
            2) "こんにちは"
            3) "user"
            4) "Taro"
      3) 1) "1565932387775-0"
         2) 1) "msg"
            2) "@Taro こんにちは!"
            3) "user"
            4) "Hanako"</pre>
<p>※UTF-8 文字列は実際にはエスケープされて出力されますが、分かりやすくするためそのまま記述しています。なお、redis-cliコマンドに&#8211;rawオプションを付けて起動するとそのまま出力できます。</p>
<h4>新着メッセージを待つ(タイムアウト60秒)</h4>
<p>XREADコマンドにBLOCKオプションを付けると、新しいメッセージが追加されるまで指定時間待ちます。IDに「$」を指定すると、XREADコマンドを発行した後に追加されたメッセージのみが対象となります。</p>
<pre>&gt; XREAD BLOCK 60000 STREAMS #channel $</pre>
<h4>誰かが60秒以内に発言する</h4>
<pre>&gt; XADD #channel * msg "Redis Streamsでチャットを作ってみたよ" user "Jiro"
"1565932616524-0"</pre>
<h4>XREAD BLOCK が返り、メッセージが取得される</h4>
<pre>1) 1) "#channel"
   2) 1) 1) "1565932616524-0"
         2) 1) "msg"
            2) "Redis Streamsでチャットを作ってみたよ"
            3) "user"
            4) "Jiro"
(2.75s)</pre>
<h4>次のメッセージを待つ(既にあれば即座に取得)</h4>
<p>連続してメッセージを取得する場合は前回取得した最後のIDを指定することに注意してください。再度「$」を指定してしまうと、途中のメッセージが抜け落ちる恐れがあります。</p>
<pre>&gt; XREAD BLOCK 60000 STREAMS #channel 1565932616524-0</pre>
<h3>監視データを複数クライアントで並列処理することを想定した場合の例</h3>
<p>1つめの例で保存した監視データをコンシューマグループを利用し、複数のクライアントで協調して処理することを想定します。</p>
<h4>ストリーム history に対してコンシューマグループ group1 を作成</h4>
<p><a href="https://redis.io/commands/xgroup">XGROUP</a>コマンドでコンシューマグループを作成します。IDに「0」を指定するとストリーム history の最初からデータを読み込みます。</p>
<pre>&gt; XGROUP CREATE history group1 0
OK</pre>
<h4>グループのメンバー C1 が他のメンバーによってまだ読まれていないデータを1つ読む</h4>
<p><a href="https://redis.io/commands/xreadgroup">XREADGROUP</a>コマンドでコンシューマグループを使用してデータを取得します。ここではコンシューマのメンバー「C1」としてデータを読みます。コンシューマがまだ存在しない場合は自動的に作成されます。IDに「&gt;」を指定すると、他のコンシューマに送信されていない新しいメッセージを要求します。</p>
<pre>&gt; XREADGROUP GROUP group1 C1 COUNT 1 STREAMS history &gt;
1) 1) "history"
   2) 1) 1) "1565915608548-0"
         2) 1) "hostid"
            2) "1234"
            3) "cpu.util"
            4) "1.2"</pre>
<h4>グループのメンバー C2 が他のメンバーによってまだ読まれていないデータを1つ読む</h4>
<p>続いてメンバーC2が同様にデータを取得します。先程C1により取得されたデータではなくその次のメッセージが返ります。</p>
<pre>&gt; XREADGROUP GROUP group1 C2 COUNT 1 STREAMS history &gt;
1) 1) "history"
   2) 1) 1) "1565915613858-0"
         2) 1) "hostid"
            2) "1350"
            3) "mem.used"
            4) "65.3"</pre>
<h4>C1 が取得したがペンディング状態のデータを確認</h4>
<p>XREADGROUPでIDに「0」を指定すると、そのメンバーが取得し、かつペンディングとなっている(XACKを返していない)データが返ります。</p>
<pre>&gt; XREADGROUP GROUP group1 C1 STREAMS history 0
1) 1) "history"
   2) 1) 1) "1565915608548-0"
         2) 1) "hostid"
            2) "1234"
            3) "cpu.util"
            4) "1.2"</pre>
<h4>取得したデータが正常に処理できたことを伝える</h4>
<p>コンシューマが取得したデータを正常に処理できたら、そのことをサーバに<a href="https://redis.io/commands/xack">XACK</a>コマンドで伝えることで一連の処理が完了します。XACKで指定したデータはペンディングエントリリストから削除されます。</p>
<pre>&gt; XACK history group1 1565915608548-0
(integer) 1</pre>
<pre>&gt; XREADGROUP GROUP group1 C1 STREAMS history 0
1) 1) "history"
2) (empty list or set)</pre>
<h4>さらにデータを読む</h4>
<p>以降も同様にメンバーC1、C2でデータを取得し、処理完了を通知します。</p>
<pre>&gt; XREADGROUP GROUP group1 C1 COUNT 1 STREAMS history &gt;
1) 1) "history"
   2) 1) 1) "1565933823472-0"
         2) 1) "hostid"
            2) "1234"
            3) "proc.num[httpd]"
            4) "5"
&gt; XREADGROUP GROUP group1 C2 COUNT 1 STREAMS history &gt;
1) 1) "history"
   2) 1) 1) "1565933855023-0"
         2) 1) "hostid"
            2) "1350"
            3) "cpu.util"
            4) "0.3"</pre>
<h4>読んだことを確認</h4>
<pre>&gt; XACK history group1 1565933823472-0
(integer) 1
&gt; XACK history group1 1565915613858-0 1565933855023-0
(integer)</pre>
<h2>おわりに</h2>
<p>今回はRedisストリームについて紹介しました。Redisストリームのデータ構造自体はシンプルですが、データにアクセスするための豊富な機能が用意されています。これにより、単純な時系列データの保存から大規模なメッセージングシステムまで、非常に柔軟な使い方が可能となっています。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>RedisをPacemakerで冗長化する</title>
		<link>https://www.sraoss.co.jp/tech-blog/pacemaker/redis-pacemaker/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Thu, 01 Aug 2019 04:10:26 +0000</pubDate>
				<category><![CDATA[Pacemaker]]></category>
		<category><![CDATA[Redis]]></category>
		<category><![CDATA[KVS]]></category>
		<category><![CDATA[OSS]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=3233</guid>

					<description><![CDATA[本稿では、Pacemaker/Corosyncを使用してRedisのクラスタを構成する方法をご紹介します。 RedisはSentinelでマスター・スレーブ構成の管理を行うことができますが、最低3個のSentinelが必 ...]]></description>
										<content:encoded><![CDATA[<p>本稿では、Pacemaker/Corosyncを使用してRedisのクラスタを構成する方法をご紹介します。<br />
RedisはSentinelでマスター・スレーブ構成の管理を行うことができますが、最低3個のSentinelが必要になります。また、仮想IPについては自前でスクリプトを作成するなどの工夫が必要になります。</p>
<p><span id="more-3233"></span></p>
<p>2ノードで完結させたい場合や、その他のリソースもあわせて管理したい場合はPacemaker/Corosyncを使用するのが便利です。Pacemakerには標準でRedisのリソースエージェントが含まれているため、比較的容易にRedisのクラスタを構築することができます。</p>
<h3>前提</h3>
<p>以下の環境を前提とします。今回はOS標準のPacemakerを使用します。</p>
<ul>
<li>OS: CentOS 7.4</li>
<li>パッケージ:
<ul>
<li>redis-5.0.5-1.el7.remi</li>
<li>pacemaker-1.1.19-8.el7_6.4</li>
<li>corosync-2.4.3-4.el7</li>
</ul>
</li>
</ul>
<table>
<tbody>
<tr>
<th>ホスト名</th>
<th>IPアドレス</th>
</tr>
<tr>
<td>server1</td>
<td>192.168.237.101</td>
</tr>
<tr>
<td>server2</td>
<td>192.168.237.102</td>
</tr>
<tr>
<td>(VIP)</td>
<td>192.168.237.150</td>
</tr>
</tbody>
</table>
<p>RedisとPacemakerのクラスタ構成は以下のようになります。</p>
<figure id="attachment_3277" aria-describedby="caption-attachment-3277" style="width: 600px" class="wp-caption alignnone"><img loading="lazy" decoding="async" class="wp-image-3277" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/07/redis-pacemaker.png" alt="" width="600" height="400" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/07/redis-pacemaker.png 837w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/07/redis-pacemaker-300x200.png 300w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/07/redis-pacemaker-768x512.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/07/redis-pacemaker-304x203.png 304w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/07/redis-pacemaker-282x188.png 282w" sizes="auto, (max-width: 600px) 100vw, 600px" /><figcaption id="caption-attachment-3277" class="wp-caption-text">RedisとPacemakerの構成</figcaption></figure>
<h3>Pacemakerのインストールと初期設定</h3>
<p>両方のノードに必要なパッケージをインストールします。なお、Redisのインストールおよびマスター・スレーブレプリケーションの設定は完了しているものとします。</p>
<pre># yum install corosync pacemaker pcs fence-agents-all</pre>
<p>クラスタを新規作成します。</p>
<pre>server1# pcs cluster auth server1 server2 -u hacluster -p (haclusterユーザのパスワード) --force
server1# pcs cluster setup --name cluster1 server1 server2</pre>
<p>corosync.conf の quorum の設定に以下を追加します。これは2ノードクラスタで片方のノード単独で起動できるようにするために必要です(理由は後述します)。</p>
<pre>quorum {
    provider: corosync_votequorum
    two_node: 1
    wait_for_all: 0  ★追加
}</pre>
<p>クラスタを起動します。</p>
<pre>server1# pcs cluster start --all

server1# pcs status
Cluster name: cluster1
Stack: corosync
Current DC: server1 (version 1.1.19-8.el7_6.4-c3c624ea3d) - partition with quorum
Last updated: Mon Jul  1 16:57:00 2019
Last change: Mon Jul  1 16:56:58 2019 by root via cibadmin on server1

2 nodes configured
0 resources configured

Online: [ server1 server2 ]

No resources


Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled</pre>
<p>今回は動作確認のためSTONITHを無効化し、1回の障害検知でフェイルオーバーするように設定します。</p>
<pre># pcs property set stonith-enabled=false
# pcs resource defaults resource-stickiness=INFINITY migration-threshold=1</pre>
<h3>Pacemakerリソースの作成</h3>
<p>仮想IPリソースを作成します。</p>
<pre># pcs resource create VIP ocf:heartbeat:IPaddr2 
  ip=192.168.237.150 cidr_netmask=24 nic=eth1 
  op monitor interval=10s</pre>
<p>Redisのマスター・スレーブリソースを作成します。Pacemakerのマスター・スレーブリソースは、複数のノードに複製され、主従関係をもつリソースです。リソースエージェントは resource-agents パッケージに含まれる ocf:heartbeat:redis を使用します。以下の例では、redisリソースおよびそのマスター・スレーブリソースを一度に作成しています。マスター・スレーブリソースはデフォルトで「&lt;リソースID&gt;-master」(redis-master)という名前が付きます。</p>
<pre># pcs resource create redis ocf:heartbeat:redis 
  op start timeout=300s 
  op monitor interval=5s 
  op monitor interval=3s role=Master 
  master</pre>
<p>VIPリソースとRedisのマスター・スレーブリソースのマスター側を colocation 制約で同じサーバに結び付けます。</p>
<pre># pcs constraint colocation add VIP with master redis-master score=INFINITY
</pre>
<p>この時点でリソースは起動しますが、一度両ノードのPacemakerを停止します。設定中にリソースを起動させたくない場合は先に両ノードをスタンバイモード(pcs node standby/unstandby)にしておいてもよいです。</p>
<pre>server2# systemctl stop pacemaker
server1# systemctl stop pacemaker</pre>
<h3>クラスタの起動</h3>
<p>Masterにしたいノード(server1)でPacemakerを起動します。</p>
<pre>server1# systemctl start pacemaker
server1# pcs status
Cluster name: cluster1
Stack: corosync
Current DC: server1 (version 1.1.19-8.el7_6.4-c3c624ea3d) - partition with quorum
Last updated: Fri Jul 19 14:20:49 2019
Last change: Fri Jul 19 14:15:52 2019 by root via crm_attribute on server2

2 nodes configured
3 resources configured

Online: [ server1 ]
OFFLINE: [ server2 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       <strong>Started server1</strong>
 Master/Slave Set: redis-master [redis]
     <strong>Masters: [ server1 ]</strong>
     Stopped: [ server2 ]

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled</pre>
<p>server1ですべてのリソースの起動が完了したことを確認したら、server2のPacemakerを起動します。</p>
<pre>server2# systemctl start pacemaker</pre>
<p>しばらく待ち、リソースの起動が正常に完了すると以下のようになります。</p>
<pre># pcs status
Cluster name: cluster1
Stack: corosync
Current DC: server1 (version 1.1.19-8.el7_6.4-c3c624ea3d) - partition with quorum
Last updated: Fri Jul 19 14:24:24 2019
Last change: Fri Jul 19 14:15:52 2019 by root via crm_attribute on server2

2 nodes configured
3 resources configured

Online: [ server1 server2 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       <strong>Started server1</strong>
 Master/Slave Set: redis-master [redis]
     <strong>Masters: [ server1 ]</strong>
     <strong>Slaves: [ server2 ]</strong>

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

# pcs constraint
Location Constraints:
Ordering Constraints:
Colocation Constraints:
  VIP with redis-master (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master)
Ticket Constraints:</pre>
<p>Redisのレプリケーションが正常に行われていることを確認します。</p>
<pre>server1# redis-cli info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.237.102,port=6379,state=online,offset=1372,lag=0

server2# redis-cli info replication
# Replication
role:slave
master_host:server1
master_port:6379
master_link_status:up</pre>
<p>また、MasterノードにVIPが割り振られていることを確認します。</p>
<pre>server1# ip -4 addr show dev eth1
3: eth1: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.237.101/24 brd 192.168.237.255 scope global eth1
       valid_lft forever preferred_lft forever
    <strong>inet 192.168.237.150/24 brd 192.168.237.255 scope global secondary eth1</strong>
       valid_lft forever preferred_lft forever

server2# ip -4 addr show dev eth1
3: eth1: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.237.102/24 brd 192.168.237.255 scope global eth1
       valid_lft forever preferred_lft forever</pre>
<h3>フェイルオーバー</h3>
<p>RedisのMasterプロセスに障害を発生させ、server2がMasterになることを確認します。</p>
<pre>server1# killall redis-server
server1# pcs status
Cluster name: cluster1
Stack: corosync
Current DC: server1 (version 1.1.19-8.el7_6.4-c3c624ea3d) - partition with quorum
Last updated: Fri Jul 19 15:34:23 2019
Last change: Fri Jul 19 15:33:18 2019 by root via crm_attribute on server2

2 nodes configured
3 resources configured

Online: [ server1 server2 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       <strong>Started server2</strong>
 Master/Slave Set: redis-master [redis]
     <strong>Masters: [ server2 ]</strong>
     Stopped: [ server1 ]

Failed Actions:
* redis_demote_0 on server1 'not running' (7): call=49, status=complete, exitreason='',
    last-rc-change='Fri Jul 19 15:33:18 2019', queued=0ms, exec=85ms


Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled</pre>
<p>redis リソースをクリーンアップし、server1がSlaveとして復旧することを確認します。</p>
<pre>server1# pcs resource cleanup redis
Cleaned up redis:0 on server2
Cleaned up redis:0 on server1
Cleaned up redis:1 on server2
Cleaned up redis:1 on server1
Waiting for 1 replies from the CRMd. OK

# pcs status resources
 VIP    (ocf::heartbeat:IPaddr2):       Started server2
 Master/Slave Set: redis-master [redis]
     Masters: [ server2 ]
     Slaves: [ server1 ]</pre>
<h3>リソース起動時の注意点</h3>
<p>Pacemaker/Corosyncの2ノードクラスタのデフォルトでは、両ノードのPacemakerが起動した時点でリソースを起動します。この場合、RedisのMasterとSlaveはほぼ同時に起動し、Masterの準備が完了していない状態でSlaveが接続しようとするため、レプリケーションの開始に失敗する場合があります。これを防ぐため、上記手順ではCorosyncの設定を変更し、Masterの起動を待ってからSlaveを起動するようにしています。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Redis Clusterについて</title>
		<link>https://www.sraoss.co.jp/tech-blog/redis/redis-cluster/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Thu, 01 Aug 2019 04:05:41 +0000</pubDate>
				<category><![CDATA[Redis]]></category>
		<category><![CDATA[KVS]]></category>
		<category><![CDATA[OSS]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=3047</guid>

					<description><![CDATA[前回のRedisの冗長化では、Redisの標準機能を用いてRedisの冗長化を行う方法についてご紹介しました。 今回はRedisでマルチマスター構成のクラスタを組むための機能であるRedis Clusterについてご紹介 ...]]></description>
										<content:encoded><![CDATA[<p>前回の<a href="https://www.sraoss.co.jp/tech-blog/redis/redis-ha/">Redisの冗長化</a>では、Redisの標準機能を用いてRedisの冗長化を行う方法についてご紹介しました。<br />
今回はRedisでマルチマスター構成のクラスタを組むための機能であるRedis Clusterについてご紹介します。</p>
<p><span id="more-3047"></span></p>
<h2>Redis Cluster</h2>
<p>Redis Cluster は Redis 3.0 で実装されました。Redis Cluster はマルチマスター構成をとり、データは複数のRedisサーバに自動的に分散されます(シャーディング)。これにより書き込み負荷を分散させることができます。Redis Cluster は一部のノードが故障しても動作を継続し、ある程度の可用性を提供しますが、多数のノードが利用不可となった場合は動作を停止します。各マスターノードにはスレーブを持たせ、可用性を向上することができます。クラスタの最小構成は3マスターノードとなります。</p>
<figure id="attachment_2995" aria-describedby="caption-attachment-2995" style="width: 520px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="wp-image-2995" src="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/06/redis-cluster-260x300.png" alt="" width="520" height="600" srcset="https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/06/redis-cluster-260x300.png 260w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/06/redis-cluster-768x886.png 768w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/06/redis-cluster-185x214.png 185w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/06/redis-cluster-225x260.png 225w, https://www.sraoss.co.jp/tech-blog/wp-content/uploads/2019/06/redis-cluster.png 856w" sizes="auto, (max-width: 520px) 100vw, 520px" /><figcaption id="caption-attachment-2995" class="wp-caption-text">RedisのCluster構成</figcaption></figure>
<p>Clusterが使用するポートは通常のポートに加え、クラスタの通信用に+10000したポート番号を使用します(6379の場合は16739)。</p>
<h3>シャーディング</h3>
<p>Redis Cluster はクラスタ全体で16384個(0～16383)のhash slotをもちます。各ノードにhash slotの一部分が割り当てられます。例えば以下のようになります。</p>
<ul>
<li>ノードA: 0～5460 の hash slot</li>
<li>ノードB: 5461～10922 の hash slot</li>
<li>ノードC: 10923～16383 の hash slot</li>
</ul>
<p>クライアントがキーを登録するとき、キーごとにhash slotの値を計算し、対応するノードにデータが格納されます。キーからhash slotの値を求めるアルゴリズムは以下のようにシンプルなものとなります。</p>
<pre>HASH_SLOT = CRC16(key) mod 16384</pre>
<p>各ノードのhash slotは後から自由に移動することができるため、後からノードを追加したりノードを削除することが可能です。</p>
<h3>Cluster の設定</h3>
<p>本来は複数台のマシンで動作させますが、今回は1台のマシン上でポート番号を変えて6台の Cluster ノードを作成します。</p>
<table>
<tbody>
<tr>
<th>名前</th>
<th>ホスト名</th>
<th>IPアドレス</th>
<th>ポート</th>
<th>クラスタポート</th>
</tr>
<tr>
<td>Node 1</td>
<td>server1</td>
<td>192.168.1.1</td>
<td>7000</td>
<td>17000</td>
</tr>
<tr>
<td>Node 2</td>
<td>server1</td>
<td>192.168.1.1</td>
<td>7001</td>
<td>17001</td>
</tr>
<tr>
<td>Node 3</td>
<td>server1</td>
<td>192.168.1.1</td>
<td>7002</td>
<td>17002</td>
</tr>
<tr>
<td>Node 4</td>
<td>server1</td>
<td>192.168.1.1</td>
<td>7003</td>
<td>17003</td>
</tr>
<tr>
<td>Node 5</td>
<td>server1</td>
<td>192.168.1.1</td>
<td>7004</td>
<td>17004</td>
</tr>
<tr>
<td>Node 6</td>
<td>server1</td>
<td>192.168.1.1</td>
<td>7005</td>
<td>17005</td>
</tr>
</tbody>
</table>
<p>ノードごとに個別のディレクトリを作成し、既存の redis.conf をコピーして設定を行います。</p>
<pre># mkdir cluster-test
# cd cluster-test/
# mkdir 7000 7001 7002 7003 7004 7005
# cp /etc/redis.conf 7000
# vi 7000/redis.conf
# cp 7000/redis.conf 7001
# vi 7001/redis.conf
...
# vi 7005/redis.conf</pre>
<p>同サーバ上で動かすため、ファイル名が重複しないように適切に設定を行います。</p>
<pre>port 7000
pidfile "/var/run/redis_7000.pid"
logfile "/root/cluster-test/7000/redis.log"
dbfilename "dump-7000.rdb"
appendonly yes
appendfilename "appendonly-7000.aof"
cluster-enabled yes
cluster-config-file nodes-7000.conf</pre>
<p>各ノードを起動します。</p>
<pre># redis-server 7000/redis.conf
# redis-server 7001/redis.conf
# redis-server 7002/redis.conf
# redis-server 7003/redis.conf
# redis-server 7004/redis.conf
# redis-server 7005/redis.conf</pre>
<p>正常にプロセスが立ち上がり、 redis.log にエラーが出力されていないことを確認します。</p>
<pre># ps auxww|grep redis
root 2939 0.1 0.1 153952 2772 ? Ssl 14:23 0:00 redis-server 0.0.0.0:7000 [cluster]
root 2980 0.1 0.1 153952 2768 ? Ssl 14:24 0:00 redis-server 0.0.0.0:7001 [cluster]
root 2985 0.2 0.1 153952 2768 ? Ssl 14:24 0:00 redis-server 0.0.0.0:7002 [cluster]
root 2990 0.2 0.1 153952 2772 ? Ssl 14:24 0:00 redis-server 0.0.0.0:7003 [cluster]
root 2995 0.3 0.1 153952 2776 ? Ssl 14:25 0:00 redis-server 0.0.0.0:7004 [cluster]
root 3000 0.7 0.1 153952 2776 ? Ssl 14:25 0:00 redis-server 0.0.0.0:7005 [cluster]</pre>
<p>/var/lib/redis 以下に各ノードの AOF およびクラスタ設定ファイルが作成されます。</p>
<pre># ls -l /var/lib/redis/
合計 24
-rw-r--r--. 1 root root 0 6月 28 14:23 appendonly-7000.aof
-rw-r--r--. 1 root root 0 6月 28 14:24 appendonly-7001.aof
-rw-r--r--. 1 root root 0 6月 28 14:24 appendonly-7002.aof
-rw-r--r--. 1 root root 0 6月 28 14:25 appendonly-7003.aof
-rw-r--r--. 1 root root 0 6月 28 14:25 appendonly-7004.aof
-rw-r--r--. 1 root root 0 6月 28 14:25 appendonly-7005.aof
-rw-r--r--. 1 root root 114 6月 28 14:23 nodes-7000.conf
-rw-r--r--. 1 root root 114 6月 28 14:24 nodes-7001.conf
-rw-r--r--. 1 root root 114 6月 28 14:24 nodes-7002.conf
-rw-r--r--. 1 root root 114 6月 28 14:25 nodes-7003.conf
-rw-r--r--. 1 root root 114 6月 28 14:25 nodes-7004.conf
-rw-r--r--. 1 root root 114 6月 28 14:25 nodes-7005.conf</pre>
<p>次に、クラスタを作成します。 &#8211;cluster-replicas 1 はマスターごとに1つのレプリカ(スレーブ)を配置することを意味します。<br />
なお、 Redis 3.0、4.0 の場合は redis-cli の代わりに redis-trib.rb という外部ツールを使用する必要があります。</p>
<pre># redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 
--cluster-replicas 1</pre>
<p>自動的にマスターとレプリカの割り当てが行われます。よければ yes を入力します。</p>
<pre>&gt;&gt;&gt; Performing hash slots allocation on 6 nodes...
Master[0] -&gt; Slots 0 - 5460
Master[1] -&gt; Slots 5461 - 10922
Master[2] -&gt; Slots 10923 - 16383
Adding replica 127.0.0.1:7004 to 127.0.0.1:7000
Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
Adding replica 127.0.0.1:7003 to 127.0.0.1:7002
&gt;&gt;&gt; Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
M: a5b82da0c32957954a3da1e16a3629083a8d5d8c 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
M: a18a55b7a4790c2bd1bd7fae057caa4144a03a52 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
S: 4d18eed5d6cdfc394f8cfa14a3655147393e3627 127.0.0.1:7003
replicates a5b82da0c32957954a3da1e16a3629083a8d5d8c
S: 04a2ad5e2b0ea06bc9d90c3ab3c4214b2ac5cce9 127.0.0.1:7004
replicates a18a55b7a4790c2bd1bd7fae057caa4144a03a52
S: 0a0dfeb8456c6bff470eddb24edae8743d6422ff 127.0.0.1:7005
replicates 70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111
Can I set the above configuration? (type 'yes' to accept): <strong>yes</strong>
&gt;&gt;&gt; Nodes configuration updated
&gt;&gt;&gt; Assign a different config epoch to each node
&gt;&gt;&gt; Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
&gt;&gt;&gt; Performing Cluster Check (using node 127.0.0.1:7000)
M: 70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 0a0dfeb8456c6bff470eddb24edae8743d6422ff 127.0.0.1:7005
slots: (0 slots) slave
replicates 70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111
S: 04a2ad5e2b0ea06bc9d90c3ab3c4214b2ac5cce9 127.0.0.1:7004
slots: (0 slots) slave
replicates a18a55b7a4790c2bd1bd7fae057caa4144a03a52
M: a5b82da0c32957954a3da1e16a3629083a8d5d8c 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: a18a55b7a4790c2bd1bd7fae057caa4144a03a52 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 4d18eed5d6cdfc394f8cfa14a3655147393e3627 127.0.0.1:7003
slots: (0 slots) slave
replicates a5b82da0c32957954a3da1e16a3629083a8d5d8c
[OK] All nodes agree about slots configuration.
&gt;&gt;&gt; Check for open slots...
&gt;&gt;&gt; Check slots coverage...
[OK] All 16384 slots covered.</pre>
<p>クラスタの構成が正常に完了すると [OK] All 16384 slots covered. というメッセージが出力されます。<br />
なお、マスターとレプリカの組み合わせを自分で決定したい場合は、<br />
最初にマスターのみでクラスタを構成した後、マスターを指定してレプリカを1つずつ追加していきます。</p>
<pre># redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002

# redis-cli --cluster add-node 127.0.0.1:7003 127.0.0.1:7000 --cluster-slave --cluster-master-id 70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111
# redis-cli --cluster add-node 127.0.0.1:7004 127.0.0.1:7001 --cluster-slave --cluster-master-id a5b82da0c32957954a3da1e16a3629083a8d5d8c
# redis-cli --cluster add-node 127.0.0.1:7005 127.0.0.1:7002 --cluster-slave --cluster-master-id a18a55b7a4790c2bd1bd7fae057caa4144a03a52</pre>
<p>任意のノードに redis-cli で接続し、 cluster nodes コマンドを実行するとノードの一覧を取得することができます。これは nodes-7000.conf とほぼ同じ内容になります。</p>
<pre># redis-cli -p 7000 cluster nodes
0a0dfeb8456c6bff470eddb24edae8743d6422ff 127.0.0.1:7005@17005 slave 70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 0 1561702297172 6 connected
70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 127.0.0.1:7000@17000 myself,master - 0 1561702298000 1 connected 0-5460
04a2ad5e2b0ea06bc9d90c3ab3c4214b2ac5cce9 127.0.0.1:7004@17004 slave a18a55b7a4790c2bd1bd7fae057caa4144a03a52 0 1561702299186 5 connected
a5b82da0c32957954a3da1e16a3629083a8d5d8c 127.0.0.1:7001@17001 master - 0 1561702296161 2 connected 5461-10922
a18a55b7a4790c2bd1bd7fae057caa4144a03a52 127.0.0.1:7002@17002 master - 0 1561702298000 3 connected 10923-16383
4d18eed5d6cdfc394f8cfa14a3655147393e3627 127.0.0.1:7003@17003 slave a5b82da0c32957954a3da1e16a3629083a8d5d8c 0 1561702298181 4 connected</pre>
<h3>Clusterの動作確認</h3>
<p>redis-cli に -c を付けるとクラスタモードになります。これで動作を確認します。</p>
<pre># redis-cli -c -p 7000
127.0.0.1:7000&gt; set foo 1
-&gt; Redirected to slot [12182] located at 127.0.0.1:7002
OK
127.0.0.1:7002&gt; get foo
"1"
127.0.0.1:7002&gt; set bar 2
-&gt; Redirected to slot [5061] located at 127.0.0.1:7000
OK
127.0.0.1:7000&gt; get bar
"2"
127.0.0.1:7000&gt; get foo
-&gt; Redirected to slot [12182] located at 127.0.0.1:7002
"1"
127.0.0.1:7002&gt; get hoge
-&gt; Redirected to slot [1525] located at 127.0.0.1:7000
(nil)
127.0.0.1:7000&gt; incr foo
-&gt; Redirected to slot [12182] located at 127.0.0.1:7002
(integer) 2
127.0.0.1:7002&gt; get foo
"2"</pre>
<p>キーに応じてslotが変化し、対応するノードに自動的に接続を切り替えていることがわかります。</p>
<h3>Clusterのクエリの制限</h3>
<p>Clusterではキーごとに格納されるノードが異なるため、クライアント側でキーに対応するノードを知る必要があります(対応するノードはサーバから通知されます)。また、キーが複数のノードにまたがっている場合、複数のキーをまとめて取得する mget のようなコマンドは失敗します。</p>
<p>複数のキーを同じノードに割り当てたい場合、ハッシュタグ({ } で囲まれた文字列)を利用することができます。キーの一部に {&#8230;} という文字列を含めることで、 { } 内の文字列のみが hash slot の計算に使用されるようになります。以下の2つのキーは同一の hash slot となり、同じノードに格納されます。</p>
<pre>{foo}hoge
{foo}fuga</pre>
<h3>フェイルオーバー</h3>
<p>7000番ポートのmasterに障害を発生させます。</p>
<pre># kill 2939
# ps auxww|grep redis
root 2980 0.1 0.1 156512 3256 ? Ssl 14:24 0:07 redis-server 0.0.0.0:7001 [cluster]
root 2985 0.1 0.1 158560 3284 ? Ssl 14:24 0:07 redis-server 0.0.0.0:7002 [cluster]
root 2990 0.2 0.2 167264 4144 ? Ssl 14:24 0:07 redis-server 0.0.0.0:7003 [cluster]
root 2995 0.2 0.1 160608 3372 ? Ssl 14:25 0:07 redis-server 0.0.0.0:7004 [cluster]
root 3000 0.2 0.1 160608 3376 ? Ssl 14:25 0:07 redis-server 0.0.0.0:7005 [cluster]</pre>
<p>cluster nodes の表示が fail となります。</p>
<pre># redis-cli -p 7001 cluster nodes
70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 127.0.0.1:7000@17000 <strong>master,fail</strong> - 1561703162227 1561703160916 1 disconnected 0-5460
a5b82da0c32957954a3da1e16a3629083a8d5d8c 127.0.0.1:7001@17001 myself,master - 0 1561703190000 2 connected 5461-10922
a18a55b7a4790c2bd1bd7fae057caa4144a03a52 127.0.0.1:7002@17002 master - 0 1561703189000 3 connected 10923-16383
04a2ad5e2b0ea06bc9d90c3ab3c4214b2ac5cce9 127.0.0.1:7004@17004 slave a18a55b7a4790c2bd1bd7fae057caa4144a03a52 0 1561703190193 3 connected
0a0dfeb8456c6bff470eddb24edae8743d6422ff 127.0.0.1:7005@17005 slave 70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 0 1561703189185 1 connected
4d18eed5d6cdfc394f8cfa14a3655147393e3627 127.0.0.1:7003@17003 slave a5b82da0c32957954a3da1e16a3629083a8d5d8c 0 1561703188000 4 connected</pre>
<p>しばらくすると自動的に7000番ポートのmasterのslaveである7005番ポートのノードがmasterに昇格し、フェイルオーバーが完了します。</p>
<pre># redis-cli -p 7001 cluster nodes
70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 127.0.0.1:7000@17000 master,fail - 1561703162227 1561703160916 1 disconnected
a5b82da0c32957954a3da1e16a3629083a8d5d8c 127.0.0.1:7001@17001 myself,master - 0 1561703238000 2 connected 5461-10922
a18a55b7a4790c2bd1bd7fae057caa4144a03a52 127.0.0.1:7002@17002 master - 0 1561703240648 3 connected 10923-16383
04a2ad5e2b0ea06bc9d90c3ab3c4214b2ac5cce9 127.0.0.1:7004@17004 slave a18a55b7a4790c2bd1bd7fae057caa4144a03a52 0 1561703242665 3 connected
0a0dfeb8456c6bff470eddb24edae8743d6422ff 127.0.0.1:7005@17005 <strong>master</strong> - 0 1561703242000 8 connected 0-5460
4d18eed5d6cdfc394f8cfa14a3655147393e3627 127.0.0.1:7003@17003 slave a5b82da0c32957954a3da1e16a3629083a8d5d8c 0 1561703240000 4 connected</pre>
<p>7000番ポートのRedisを再度起動すると、7005番ポートのmasterのslaveとして立ち上がり、再同期が行われます。</p>
<pre># redis-server 7000/redis.conf
# redis-cli -p 7001 cluster nodes
70ed8f0f72ee70d2b55adfa722fcf1f9eb0c8111 127.0.0.1:7000@17000 <strong>slave</strong> 0a0dfeb8456c6bff470eddb24edae8743d6422ff 0 1561703557658 8 connected
a5b82da0c32957954a3da1e16a3629083a8d5d8c 127.0.0.1:7001@17001 myself,master - 0 1561703558000 2 connected 5461-10922
a18a55b7a4790c2bd1bd7fae057caa4144a03a52 127.0.0.1:7002@17002 master - 0 1561703559675 3 connected 10923-16383
04a2ad5e2b0ea06bc9d90c3ab3c4214b2ac5cce9 127.0.0.1:7004@17004 slave a18a55b7a4790c2bd1bd7fae057caa4144a03a52 0 1561703556649 3 connected
0a0dfeb8456c6bff470eddb24edae8743d6422ff 127.0.0.1:7005@17005 master - 0 1561703558000 8 connected 0-5460
4d18eed5d6cdfc394f8cfa14a3655147393e3627 127.0.0.1:7003@17003 slave a5b82da0c32957954a3da1e16a3629083a8d5d8c 0 1561703558667 4 connected</pre>
<h2>おわりに</h2>
<p>今回はRedisの標準機能の一つであるRedis Clusterについて紹介しました。Redis Clusterは必要なサーバ台数が多くなるものの、負荷分散と可用性を両立させることができます。</p>
<p>次回はPacemakerを用いたRedisの冗長化について紹介します。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Redisのデータ永続化</title>
		<link>https://www.sraoss.co.jp/tech-blog/redis/redis-persistdata/</link>
		
		<dc:creator><![CDATA[山本 博之 (Hiroyuki Yamamoto)]]></dc:creator>
		<pubDate>Mon, 24 Jun 2019 01:00:19 +0000</pubDate>
				<category><![CDATA[Redis]]></category>
		<category><![CDATA[KVS]]></category>
		<category><![CDATA[OSS]]></category>
		<guid isPermaLink="false">https://www.sraoss.co.jp/tech-blog/?p=2728</guid>

					<description><![CDATA[インメモリDBとデータの永続化 前回のRedisの紹介では、Redisの特長や導入手順、基本的な使い方についてご紹介しました。本稿では、インメモリデータベースのデータ永続化についてご紹介します。 Redisはインメモリデ ...]]></description>
										<content:encoded><![CDATA[<h2>インメモリDBとデータの永続化</h2>
<p>前回の<a href="https://www.sraoss.co.jp/tech-blog/redis/redis-introduction/">Redisの紹介</a>では、Redisの特長や導入手順、基本的な使い方についてご紹介しました。本稿では、インメモリデータベースのデータ永続化についてご紹介します。</p>
<p>Redisはインメモリデータベースであるため、サーバプロセスが終了するとメモリ上のデータも消えてしまいます。そこで、Redisはサーバプロセス終了後もデータを保持するための2種類の機能が用意されています。</p>
<p><span id="more-2728"></span></p>
<h3>RDB</h3>
<p>Redisでは特定の時点のスナップショットをRDBファイルとして保存することができます。RDBはデータベースのダンプファイルに相当します。SAVEコマンドおよびBGSAVEコマンドで現時点のスナップショットを保存できます。また、設定により、一定の書き込み数と時間の経過により自動的にデータを保存することもできます。デフォルトの設定は以下のようになっており、条件を満たした場合にデータが自動保存されます。なお、「save &#8220;&#8221;」と設定することで自動保存を無効化することも可能です。</p>
<ul>
<li>900秒後に1個以上のキーが変更</li>
<li>300秒後に10個以上のキーが変更</li>
<li>60秒後に10000個以上のキーが変更</li>
</ul>
<pre>save 900 1
save 300 10
save 60 10000</pre>
<p>RDBファイルはRedisの起動時に自動的に読み込まれ、前回終了時のデータが復元されます。</p>
<h3>AOF (Append Only File)</h3>
<p>多くの場合は前述のRDBファイルの自動保存でも十分ですが、サーバプロセスの障害や電源断などが発生した場合、直近の数分程度のデータを失う可能性があります。</p>
<p>この問題を回避するのがAOF (Append Only File)となります。</p>
<p>AOFはデータベースのWAL/REDOログに似た書き込みログで、すべての書き込みコマンドが追記で記録されます。AOFはデフォルトでは1秒ごとにfsyncによりディスクに同期される(appendfsync everysec)ので、データを失う可能性のある期間は1秒以内に抑えられます。なお、1回の書き込みごとにfsyncを呼び出すようにする(appendfsync always)こともできますが、非常に遅くなります。</p>
<p>AOFはデフォルトでは無効です。以下の設定で有効にすることができます。また、RDBと同時に使用することもでき、AOFとRDBを両方有効にすることが推奨されています。</p>
<pre>appendonly yes</pre>
<p>AOFファイルはRedisの起動時に自動的に読み込まれます。AOFファイルとRDBファイルの両方が存在する場合はAOFファイルが優先されます。なお、AOFファイルが存在しない状態でAOFを有効にして再起動すると空のAOFファイルを作成するため、<strong>すべてのデータが初期化されてしまう</strong>のでご注意ください。</p>
<h2>バックアップ</h2>
<h3>RDB</h3>
<p>前述の通り、SAVEコマンドもしくはBGSAVEコマンドで現時点のデータのスナップショットをRDBファイルに保存することができます。SAVEコマンドは他のクライアントからのアクセスをすべてブロックしてしまうため、通常はバックグラウンドでデータを保存するBGSAVEコマンドを使用します。BGSAVEコマンドが完了したかどうかはLASTSAVEコマンドで確認できます。RDBファイルはRedisサーバプロセス終了時にも保存されます。</p>
<pre>127.0.0.1:6379&gt; save #保存が完了するまで他の操作はすべてブロックされる
OK
127.0.0.1:6379&gt; lastsave #最終保存時刻(Unix時間)を確認
(integer) 1559267764
127.0.0.1:6379&gt; bgsave #バックグラウンドで保存(すぐに処理が返ってくる)
Background saving started
127.0.0.1:6379&gt; lastsave #最終保存時刻が更新されていることを確認
(integer) 1559267778</pre>
<p>RHEL 7 / CentOS 7のRemiリポジトリのRedisパッケージでは、デフォルトで以下の場所にRDBファイルが保存されます。</p>
<pre>/var/lib/redis/dump.rdb</pre>
<p>このファイルを別の安全な場所に保存します。なお、RDBファイルはアトミックに作成されるので、中途半端な状態のファイルを保存してしまう心配はありません。</p>
<pre># cp /var/lib/redis/dump.rdb /path/to/redis-dump-YYYYMMDD.rdb</pre>
<p>redis-check-rdbコマンドでRDBファイルの正常性を確認することができます。</p>
<pre># redis-check-rdb /tmp/redis-backup-20190531.rdb
[offset 0] Checking RDB file /tmp/redis-backup-20190531.rdb
[offset 26] AUX FIELD redis-ver = '5.0.5'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1559268270'
[offset 67] AUX FIELD used-mem = '1860912'
[offset 83] AUX FIELD aof-preamble = '0'
[offset 85] Selecting DB ID 0
[offset 14677] Checksum OK
[offset 14677] o/ RDB looks OK! o/
[info] 6 keys read
[info] 0 expires
[info] 0 already expired</pre>
<h3>AOF</h3>
<p>RDBのみ有効にした状態からAOFを有効にするには以下のようにします。なお、redis.confのみ修正して再起動すると、前述の通りすべてのデータが初期化されてしまうのでご注意ください。</p>
<pre># redis-cli config set appendonly yes
OK
# vi /etc/redis.conf
appendonly no
↓ 修正
appendonly yes</pre>
<p>デフォルトでは以下の場所にAOFファイルが保存されます。</p>
<pre>/var/lib/redis/appendonly.aof</pre>
<p>AOFは追記型のため、RDBに比べてファイルサイズが大きくなります。そのためバックアップの取得にはRDBが適しています。BGREWRITEAOFコマンドでAOFを再構成し、ファイルサイズを縮小できます。再構成は自動でも行われます。</p>
<pre># ls -l /var/lib/redis/
合計 64152
-rw-r--r--. 1 redis redis 65614804 5月 31 11:32 appendonly.aof
-rw-r--r--. 1 redis redis 21887 5月 31 11:33 dump.rdb
# redis-cli bgrewriteaof
Background append only file rewriting started
# ls -l /var/lib/redis/
合計 48
-rw-r--r--. 1 redis redis 21887 5月 31 11:37 appendonly.aof
-rw-r--r--. 1 redis redis 21887 5月 31 11:33 dump.rdb</pre>
<p>redis-check-aofコマンドでAOFファイルの正常性を確認することができます。</p>
<pre># redis-check-aof /var/lib/redis/appendonly.aof
The AOF appears to start with an RDB preamble.
Checking the RDB preamble to start:
[offset 0] Checking RDB file /var/lib/redis/appendonly.aof
[offset 26] AUX FIELD redis-ver = '5.0.5'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1559269522'
[offset 67] AUX FIELD used-mem = '1859808'
[offset 83] AUX FIELD aof-preamble = '1'
[offset 85] Selecting DB ID 0
[offset 14677] Checksum OK
[offset 14677] o/ RDB looks OK! o/
[info] 6 keys read
[info] 0 expires
[info] 0 already expired
RDB preamble is OK, proceeding with AOF tail...
AOF analyzed: size=65614804, ok_up_to=65614804, diff=0
AOF is valid</pre>
<h2>リストア</h2>
<h3>RDB</h3>
<p>AOFは無効で、RDBのみ使用している場合は以下のようにしてリストアします。</p>
<h4>1. Redisを停止</h4>
<pre># systemctl stop redis</pre>
<h4>2. RDBファイルを書き戻す</h4>
<pre># mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak
# cp /path/to/redis-dump-YYYYMMDD.rdb /var/lib/redis/dump.rdb
# chown redis:redis /var/lib/redis/dump.rdb</pre>
<h4>3. Redisを起動</h4>
<pre># systemctl start redis</pre>
<h3>AOF</h3>
<p>AOFファイルからリストアする場合は次のようにします。</p>
<h4>1. Redisを停止</h4>
<pre># systemctl stop redis</pre>
<h4>2. AOFファイルを書き戻す</h4>
<pre># mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak (RDBも有効の場合)
# mv /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof.bak 
# cp /path/to/redis-appendonly-YYYYMMDD.aof /var/lib/redis/appendonly.aof
# chown redis:redis /var/lib/redis/appendonly.aof</pre>
<h4>3. Redisを起動</h4>
<pre># systemctl start redis</pre>
<h3>RDB (AOF有効時)</h3>
<p>AOFを有効にしている場合にRDBファイルからリストアする場合は注意が必要です。前述の通り、AOFファイルがない場合は起動時に空のAOFファイルを作成し、そちらを参照するため、RDBファイルを配置しても無視されてデータが初期化されてしまいます。そのため、以下の手順のように、AOFを一時的に無効化してRDBファイルからリストアした後AOFを再作成し、AOFの設定を有効化する必要があります。</p>
<h4>1. Redisを停止</h4>
<pre># systemctl stop redis</pre>
<h4>2. RDBファイルを書き戻す</h4>
<pre># mv /var/lib/redis/dump.rdb /var/lib/redis/dump.rdb.bak
# mv /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof.bak
# cp /path/to/redis-dump-YYYYMMDD.rdb /var/lib/redis/dump.rdb
# chown redis:redis /var/lib/redis/dump.rdb</pre>
<h4>3. AOFを無効化してRedisを起動</h4>
<pre># vi /etc/redis.conf
appendonly yes → appendonly no

# systemctl start redis</pre>
<h4>4. AOFファイルを書き出す</h4>
<pre># redis-cli bgrewriteaof
Background append only file rewriting started
# redis-cli info | grep aof_rewrite_in_progress
aof_rewrite_in_progress:0
# ls -l /var/lib/redis/
合計 80
-rw-r--r--. 1 redis redis 14677 5月 31 15:21 appendonly.aof
-rw-r--r--. 1 redis redis 21887 5月 31 11:37 appendonly.aof.bak
-rw-r--r--. 1 redis redis 14677 5月 31 15:19 dump.rdb
-rw-r--r--. 1 redis redis 21887 5月 31 14:33 dump.rdb.bak</pre>
<h4>5. AOFを有効化してRedisを再起動</h4>
<pre># systemctl stop redis
# vi /etc/redis.conf
appendonly no → appendonly yes
# systemctl start redis</pre>
<h2>おわりに</h2>
<p>Redisはインメモリデータベースですが、データの永続化が可能となっています。Redisのバックアップ・リストアも非常に簡単で、AOFにより耐障害性の向上も図ることができます。しかしながら、RDBとAOFを両方使用する場合の操作については注意が必要なところがあります。</p>
<div>
<a href="https://www.sraoss.co.jp/prod_serv/support/oss-pro-support/?utm_source=sraoss-techblog&utm_medium=referral&utm_campaign=under-article-oss" rel="noopener" style="color:initial;" target="_blank" class="no-ext"></p>
<div style="background-color:#DAEFF6; padding:20px; border-radius:8px; text-align:center;">
SRA OSSでは、各種OSS のサポートを提供しております。<br />
詳しくは<strong style="color:#2581c4;">弊社ホームページ</strong>をご覧ください。
</div>
<p></a>
</div>

]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
