かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その13 )( Spring Session を使用する2 )

概要

Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その12 )( Spring Session を使用する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • ログイン画面及びログイン URL ( /login ) で CSRF 対策を外す方法があるのか?
    • Tomcat, Redis を複数起動して試してみる ( 今回だけでは終わらなかったため、次回へ続きます )

参照したサイト・書籍

  1. Spring Security Reference - 6. Cross Site Request Forgery (CSRF)
    http://docs.spring.io/spring-security/site/docs/3.2.8.RELEASE/reference/htmlsingle/#csrf

    • Spring Security の公式サイトのマニュアルの CSRF 対策の部分です。
  2. TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.0.0.RELEASE documentation - 6.7. CSRF対策
    http://terasolunaorg.github.io/guideline/5.0.0.RELEASE/ja/Security/CSRF.html

    • TERASOLUNA のドキュメントの CSRF 対策の章です。Spring Security の CSRF 対策について理解したい時はこのドキュメントが一番詳しく、かつ分かりやすいと思います。
  3. Siguniang's Blog - Redis:レプリケーション設定
    https://siguniang.wordpress.com/2012/02/20/redis_replication/

  4. Redis Sentinel Documentation
    http://redis.io/topics/sentinel

    • Resis Sentinel の公式ドキュメントです。
  5. GMOメディア エンジニアブログ - Redis Sentinelを運用してみたお話
    http://tech.gmo-media.jp/post/48748908427/introduce-redis-sentinel

    • Redis Sentinel の設定方法を参考にしました。
  6. Redis Sentinelで自動フェイルオーバー
    http://qiita.com/wellflat/items/8935016fdee25d4866d9

    • Redis Sentinel の設定方法を参考にしました。
  7. Redis の冗長化を考える (keepalived, HAProxy, Redis Sentinel)
    https://blog.1q77.com/2015/02/redis-ha/

  8. Redis 2.8 の Sentinel の動きを検証してみた
    http://chrone.hatenablog.com/entry/2014/02/28/212616

  9. Redis Sentinelを動かしてみた
    http://blog.kenjiskywalker.org/blog/2013/01/24/redis-sentiel-howto/

目次

  1. はじめに
  2. commit する
  3. ログイン画面及びログイン URL ( /login ) で CSRF 対策を外す方法があるのか?
    1. そもそも form タグ内に CSRF トークン ( _csrf の hidden フィールド ) が出力される仕組みとは?
    2. ログイン画面の form タグ内に CSRF トークン ( _csrf の hidden フィールド ) が出力されないようにする
    3. ログイン URL ( /login ) を CSRF 対策の処理対象外にする
    4. 変更を元に戻す
  4. Tomcat, Redis を複数起動して試してみる
    1. Redis が起動しない。。。
    2. 2台目の Redis を起動する
    3. Redis を複数起動してデータを共有するには?
    4. Redis 2台を master - slave のレプリケーション構成に設定する
    5. Redis Sentinel の管理プロセスを起動する
    6. 自動フェイルオーバーするか確認する
  5. 次回は。。。

手順

はじめに

Spring Boot で書籍の貸出状況確認・貸出申請する Web アプリケーションを作る ( その12 )( Spring Session を使用する ) からの Spring Session の動作確認の続きです。

commit する

  1. ここまでの変更内容を commit します。「Code Analysis」ダイアログが出ますが、無視して「Commit」ボタンをクリックします。

ログイン画面及びログイン URL ( /login ) で CSRF 対策を外す方法があるのか?

Spring Security の公式サイトのマニュアルの 6.5.2. Logging In には CSRF 対策をした方がよいと書かれていますが、CSRF を外すにはどうすればよいのかということに興味が出たので、ログイン画面及びログイン URL ( /login ) で CSRF 対策を外す方法を調べてみます。

今回調べる内容は develop/1.0.0 ブランチにはマージしません。

そもそも form タグ内に CSRF トークン ( _csrf の hidden フィールド ) が出力される仕組みとは?

調べたところ、以下の仕組みのようです。

  • org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor の processAction メソッドで GET, HEAD, TRACE, OPTIONS 以外の場合には出力するよう判定されています。
  • 同じ CsrfRequestDataValueProcessor の getExtraHiddenFields メソッドで出力する _csrf の hidden フィールドの内容がセットされています。
  • 以前 Spring Boot でログイン画面 + 一覧画面 + 登録画面の Webアプリケーションを作る ( その9 )( ログイン画面作成2 ) の「検索/一覧画面のページネーション用に作成した form に自動で CSRF対策用の hidden が出力されない原因を調査する」に書きましたが、form タグに th:action を書いていると _csrf の hidden フィールドが form タグ内に出力されます。
  • CsrfRequestDataValueProcessor が適用される仕組みが分かりませんでした。WebSecurityConfigurerAdapter クラスの継承クラス WebSecurityConfig の configure メソッド内で http.csrf().disable() が呼び出されていなければ必ず適用される仕組みと思われるのですが。。。

ログイン画面の form タグ内に CSRF トークン ( _csrf の hidden フィールド ) が出力されないようにする

login.html を見たら form タグに th:action を書いていました。_csrf の hidden フィールドが出力されている原因はこれですので、削除してみます。

  1. src/main/resources/templates の下の login.html を リンク先の内容 に変更します。

  2. 確認します。Gradle projects View から bootRun タスクを実行して Tomcat を起動します。

  3. Redis のデータをクリアします。

    f:id:ksby:20150726140723p:plain

  4. ブラウザを起動して http://localhost:8080/ にアクセスし、ログイン画面を表示します。

    </form> の直前に出力されていた _csrf の hidden フィールドが出力されていませんでした。

    f:id:ksby:20150726140944p:plain

  5. Redis の方にもデータは追加されていませんでした。ふと思いましたが、これまでは Tomcat 側のセッションデータの作成状況を確認する方法はなかったのですが、Spring Session で Redis に保存すると確認できるようになるのがいいですね。

    f:id:ksby:20150726141224p:plain

  6. /login URL は POST メソッドで呼び出しており Spring Security の CSRF 機能が有効ですので、ログインしようとしてもエラー画面が表示されます。

    f:id:ksby:20150726141512p:plain

ログイン URL ( /login ) を CSRF 対策の処理対象外にする

http.csrf() から requireCsrfProtectionMatcher メソッドというものが呼び出せたので、おそらくこれを実装すれば対象外の URL を設定できるものと思われます。試してみます。

  1. src/main/java/ksbysample/webapp/lending/config の下の WebSecurityConfig.javaリンク先の内容 に変更します。

  2. Ctrl+F5 を押して Tomcat を再起動します。

  3. ブラウザを起動して http://localhost:8080/ にアクセスし、ログイン画面を表示します。ID に "tanaka.taro@sample.com"、Password に "taro" を入力して、「次回から自動的にログインする」をチェックせずに「ログイン」ボタンをクリックします。

    今度はエラー画面は表示されず「ログイン成功!」の画面が表示されました。

    f:id:ksby:20150726181306p:plain

  4. Ctrl+F2 を押して Tomcat を停止します。

変更を元に戻す

  1. intelliJ IDEA のメイン画面下部の「Terminal」をクリックして Terminal 画面を開いた後、git reset --hard コマンドを実行して変更した内容を元に戻します。

Tomcat, Redis を複数起動して試してみる

Redis が起動しない。。。

  1. 2台目の Redis を起動するために調査していた時に「サービス」画面から Redis が起動しない現象が発生しました。この起動しない状態になった時でも Windows を再起動すると起動しました。調査したところ、C:\Redis\2.8.21\redis.windows-service.conf に maxheap が設定されておらず、どうも起動時にメモリ不足と判断されているようです。

  2. maxheap を設定します。C:\Redis\2.8.21 の下の redis.windows-service.conf を リンク先のその1の内容 に変更します。

  3. 「サービス」画面から Redis を再起動します。

    f:id:ksby:20150726222035p:plain

2台目の Redis を起動する

Redis をインストールした C:\Redis\2.8.21 の中に Windows Service Documentation.docx というファイルがあり、その中に複数 Redis を起動する場合の方法が記述されています。それに従い2台目を設定・起動します。

C:\Redis\2.8.21 の下の redis.windows-service.conf をコピーして、同一ディレクトリ内に redis2.windows-service.conf を作成します。作成後、リンク先のその1の内容 に変更します。

コマンドラインを「管理者として実行...」で起動します。

以下のコマンドを実行して2台目の Redis をサービスとして登録・起動します。

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>cd /d C:\Redis\2.8.21

C:\Redis\2.8.21>redis-server --service-install redis2.windows-service.conf --service-name redis2

C:\Redis\2.8.21>redis-server --service-start --service-name redis2
[5420] 26 Jul 23:30:00.393 # Redis service successfully started.

C:\Redis\2.8.21>

「サービス」画面を開いて redis2 サービスが登録されており、かつ起動していることを確認します。

f:id:ksby:20150726233231p:plain

コマンドプロンプトから netstat コマンドを実行して 6380番ポートで LISTEN されていることを確認します。

f:id:ksby:20150726234026p:plain

Redis を複数起動してデータを共有するには?

調べた感じでは以下のようです。

  • Redis でクラスタ機能が提供されているは version 3 から。現在インストールしている Windows 版の 2.8 ではクラスタ機能は使用できませんが、レプリケーション機能が使用できます。
  • レプリケーション機能は master - slave 構成のみ。master - master 構成にはできません。
  • master - slave 構成の場合、デフォルトでは slave 側は書き込み不可ですが、設定変更すれば書き込み可能にできます。
  • レプリケーションの master - slave 構成の設定、及び slave 構成の書き込み可の設定は、設定ファイルでも redis-cli コマンドでもどちらからでも設定可能です。
  • Redis Sentinel という管理プロセスを起動すればレプリケーションの master - slave 構成で自動フェイルオーバーが実現できます。Windows 版でも redis-server.exe に --sentinel オプションを付けて起動すれば、そのサーバは Redis Sentinel になるようです。
  • Spring Data Redis では Redis Sentinel がサポートされており、設定ファイルを変更しなくても自動フェイルオーバー後に自動的に master に昇格した Redis へ接続するようです。

よって、以下の内容で Redis を複数起動してデータを共有してみます。

  • Resis は2台起動して master - slave のレプリケーション構成にします。また Redis Sentinel を利用して自動フェイルオーバーするようにしてみます。
  • データ保存用の Redis を2台、Redis Sentinel の管理プロセスを3台、localhost で以下のポート番号で起動します。

    ポート番号 役割
    6379 Redis 1
    6380 Redis 2
    6381 Redis Sentinel 1
    6382 Redis Sentinel 2
    6383 Redis Sentinel 3
  • Redis Sentinel も Windows のサービスで起動します。

Redis 2台を master - slave のレプリケーション構成に設定する

  1. C:\Redis\2.8.21 の下の redis.windows-service.conf を リンク先のその2の内容 に変更します。

  2. C:\Redis\2.8.21 の下の redis2.windows-service.conf を リンク先のその2の内容 に変更します。

  3. 「サービス」画面から Redis, redis2 を再起動します。

    f:id:ksby:20150729181240p:plain

  4. redis-cli コマンドで 6379番ポートの Redis の設定を info replication コマンドで確認します。こちらが master で、かつ connected_slaves が 1 になっていることが確認できます。

    f:id:ksby:20150729181434p:plain

  5. 6380番ポートの Redis の設定を info replication コマンドで確認します。こちらが slave で、master が 127.0.0.1:6379 であること、かつ slave_priority が 4 になっていることが確認できます。

    f:id:ksby:20150729181709p:plain

  6. 動作確認します。redis-cli で 6379, 6380番ポートの各 Redis に接続し、データがないことを確認します。

    ConEmu というソフトウェアで上下にコマンドラインを並べて実行しています。

    f:id:ksby:20150729182111p:plain

  7. 6379番ポートの Redis にデータをセットすると、6380番ポートの Redis にデータが反映されていることが確認できます。

    f:id:ksby:20150729182546p:plain

  8. 6379番ポートの Redis で追加したデータを削除すると、6380番ポートの Redis にも反映されてデータが削除されていることが確認できます。

    f:id:ksby:20150729182718p:plain

Redis Sentinel の管理プロセスを起動する

C:\Redis\2.8.21 の下の redis.windows-service.conf をコピーして、同一ディレクトリ内に redis-sentinel.windows-service.conf.org を作成します。作成後、リンク先の内容 に変更します。

※Redis Sentinel の設定ファイルは、起動した管理プロセスにより設定ファイルの内容が変更されるため、最初に元となるファイルを作成しておきます。

redis-sentinel.windows-service.conf.org をコピーして、同一ディレクトリ内に redis-sentinel1.windows-service.conf, redis-sentinel2.windows-service.conf, redis-sentinel3.windows-service.conf を作成します。作成後、リンク先の内容 に変更します。

コマンドラインを「管理者として実行...」で起動します。

以下のコマンドを実行して Redis Sentinel の管理プロセス3台分をサービスとして登録・起動します。

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>cd /d C:\Redis\2.8.21

C:\Redis\2.8.21>redis-server --service-install --service-name redis-sentinel1 re
dis-sentinel1.windows-service.conf --sentinel

C:\Redis\2.8.21>redis-server --service-start --service-name redis-sentinel1
[2288] 29 Jul 19:53:36.284 # Redis service successfully started.

C:\Redis\2.8.21>redis-server --service-install --service-name redis-sentinel2 re
dis-sentinel2.windows-service.conf --sentinel

C:\Redis\2.8.21>redis-server --service-start --service-name redis-sentinel2
[11204] 29 Jul 19:58:32.941 # Redis service successfully started.

C:\Redis\2.8.21>redis-server --service-install --service-name redis-sentinel3 re
dis-sentinel3.windows-service.conf --sentinel

C:\Redis\2.8.21>redis-server --service-start --service-name redis-sentinel3
[11084] 29 Jul 19:59:36.977 # Redis service successfully started.

「サービス」画面を開き、サービスとして登録されていること、サービスが起動していることを確認します。

f:id:ksby:20150729204453p:plain

redis-cli コマンドで 6381, 6382, 6383番ポートの Redis Sentinel へ接続して info sentinel コマンドを実行し、Redis のサーバの master 側が認識されていることを確認します。

f:id:ksby:20150731004802p:plain

ちなみにこの時点で redis-sentinel1.windows-service.conf を開くと、以下のように設定ファイルの中身が変更されています。

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 1500
sentinel failover-timeout mymaster 90000
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-sentinel mymaster 127.0.0.1 6382 ed0e4ca8671d46c6531289f40a6a6520de126ae3
sentinel known-sentinel mymaster 127.0.0.1 6383 6ee2d24fbe2430e1040963c88e72e05f00fa2008
sentinel current-epoch 0

自動フェイルオーバーするか確認する

  1. redis-cli コマンドで 6379, 6380番ポートの Redis へ接続して、データが登録されていないことと、現在の Redis のレプリケーション構成 ( どちらが master でどちらが slave か ) を確認します。

    f:id:ksby:20150729201817p:plain

  2. データを1件登録して、レプリケーションされていることを確認します。

    f:id:ksby:20150729202007p:plain

  3. 6379番ポートの Redis を shutdown します。shutdown 後、6380番ポートの Redis で info replication コマンドを実行すると master に昇格していることが確認できます。

    f:id:ksby:20150729202226p:plain

  4. 6380番ポートの Redis でデータを変更します。

    f:id:ksby:20150729202630p:plain

  5. 6379番ポートの Redis を「サービス」画面から起動します。

    f:id:ksby:20150729204305p:plain

  6. redis-cli コマンドで 6379 番ポートの Redis へ接続して info replication コマンドを実行します。今度は 6379番ポートの Redis が slave になっています。

    f:id:ksby:20150729203008p:plain

  7. 6379番ポートの Redis でデータの内容を確認すると、6380番ポートの Redis でセットした内容が表示されました。

    f:id:ksby:20150729203424p:plain

  8. 6380番ポートの Redis を shutdown します。shutdown 後、6379番ポートの Redis で info replication コマンドを実行すると master に戻っていることが確認できます。

    f:id:ksby:20150729203715p:plain

  9. 6379番ポートの Redis でデータを変更します。

    f:id:ksby:20150729203935p:plain

  10. 6380番ポートの Redis を「サービス」画面から起動します。

    f:id:ksby:20150729204210p:plain

  11. redis-cli コマンドで 6379, 6380 番ポートの Redis へ接続して info replication コマンドを実行すると、なぜか 6379番ポートの Redis が slave、6380番ポートの Redis が master になっていました。。。 6379番ポートの Redis で変更したデータも元に戻ってしまっています。

    ※画像のデータが上の画像と繋がっていないのは、この現象が起きて不思議に思い、何度もやり直したためです。

    f:id:ksby:20150729205642p:plain

    6379番ポートの Redis が master のまま、変更したデータが 6380番ポートの Redis で表示されるはずだったのですが、何が悪かったのでしょうか? 調べてみます。

  12. 調査した結果、6379番ポートの Redis が slave に変わった時に redis.windows-service.conf の最後に slaveof 127.0.0.1 6380 という設定が追加されており、redis2.windows-service.conf からは slaveof 127.0.0.1 6379 の設定が消えていました。この設定のために 6379番ポートの Redis が起動すると master にはならず必ず slave になっていたようです。

  13. 今度は 6379番ポートの Redis が master のままになるようにしてみます。以下の手順で問題が出た直前の状態まで進めます。

    1. Redis 2台、Redis Sentinel 3台のサービスを全て停止し、設定を元に戻します。
    2. Redis 2台を起動し、master ( 6379番ポート側 ) - slave ( 6380番ポート側 ) 構成にします。
    3. 上の手順を再度実行し、6380番ポートの Redis を起動する手前まで実行します。

    f:id:ksby:20150729225847p:plain

    redis.windows-service.conf の最後に slaveof 127.0.0.1 6380 が追加されていることも確認します。

  14. 6379 番ポートの Redis で slaveof no one コマンドを実行して slave の設定を削除します。

    f:id:ksby:20150729230202p:plain

    redis.windows-service.conf の最後から slaveof 127.0.0.1 6380 の設定が削除されました。

  15. redis2.windows-service.conf の最後に slaveof 127.0.0.1 6379 の設定を追加します。

  16. 6380番ポートの Redis を「サービス」画面から起動します。

    f:id:ksby:20150729204210p:plain

  17. redis-cli コマンドで 6379, 6380 番ポートの Redis へ接続して info replication コマンドを実行します。今度は 6379番ポートの Redis は master のまま変わっておらず、6380番ポートの Redis は slave になりました。

    f:id:ksby:20150729231035p:plain

  18. 6380番ポートの Redis でデータの内容を確認すると、6379番ポートの Redis でセットした内容が表示されました。

    f:id:ksby:20150729231150p:plain

Redis Sentinel だけでなく通常の Redis も設定ファイルを書き換えるんですね。。。 設定ファイルを書き換えるサーバなんて初めて見ました。Windows 版固有の現象なのか、それとも Linux 版とかでも出る現象なのかが気になりますが、一旦今はこのまま進めます。

次回は。。。

Tomcat, Redis を複数起動して試してみる」の続きです。Redis を複数サーバ構成にする方法を調べるのに時間がかかりすぎました。。。

ソースコード

login.html

                            <form role="form" action="/login" method="post" id="login-form" autocomplete="off">
  • <form role="form" action="#" th:action="@{/login}" method="post" id="login-form" autocomplete="off"><form role="form" action="/login" method="post" id="login-form" autocomplete="off"> へ変更します。

WebSecurityConfig.java

package ksbysample.webapp.lending.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 認証の対象外にしたいURLがある場合には、以下のような記述を追加します
                // 複数URLがある場合はantMatchersメソッドにカンマ区切りで対象URLを複数列挙します
                // .antMatchers("/country/**").permitAll()
                .antMatchers("/fonts/**").permitAll()
                .antMatchers("/html/**").permitAll()
                .antMatchers("/encode").permitAll()
                .anyRequest().authenticated();

        http.formLogin()
                .loginPage("/")
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/loginsuccess")
                .failureUrl("/")
                .usernameParameter("id")
                .passwordParameter("password")
                .permitAll()
                .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID")
                .deleteCookies("remember-me")
                .invalidateHttpSession(true)
                .permitAll()
                .and()
                .rememberMe()
                .key("ksbysample-webapp-lending")
                .tokenValiditySeconds(60 * 60 * 24 * 30);

        http.csrf()
                .requireCsrfProtectionMatcher(new RequestMatcher() {
                    private Pattern DISABLE_CSRF_TOKEN_PATTERN = Pattern.compile("(?i)^(GET|HEAD|TRACE|OPTIONS)$");
                    private Pattern DISABLE_CSRF_URI_PATTERN = Pattern.compile("^(/login)$");

                    @Override
                    public boolean matches(HttpServletRequest request) {
                        if (request != null) {
                            if (DISABLE_CSRF_TOKEN_PATTERN.matcher(request.getMethod()).matches()) {
                                return false;
                            } else if (DISABLE_CSRF_URI_PATTERN.matcher(request.getRequestURI()).matches()) {
                                return false;
                            }
                        }
                        return true;
                    }
                });
    }

    @Bean
    public AuthenticationProvider daoAuhthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
        daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
        return daoAuthenticationProvider;
    }

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(daoAuhthenticationProvider())
                .userDetailsService(userDetailsService);
    }

}
  • configure メソッド内に http.csrf().requireCsrfProtectionMatcher(...); を追加します。
  • DISABLE_CSRF_TOKEN_PATTERN による HTTP メソッドのチェックをしないと GET メソッドCSRF トークンのチェックが行われるようになり、ログイン画面自体が表示されなくなります。

redis.windows-service.conf

■その1

# The Redis heap must be larger than the value specified by the maxmemory
# flag, as the heap allocator has its own memory requirements and
# fragmentation of the heap is inevitable. If only the maxmemory flag is
# specified, maxheap will be set at 1.5*maxmemory. If the maxheap flag is
# specified along with maxmemory, the maxheap flag will be automatically
# increased if it is smaller than 1.5*maxmemory.
#
# maxheap <bytes>
maxheap 104857600
  • # maxheap <bytes> の行の下に maxheap 104857600 を追加します ( 100MB で設定します )。

■その2

# You can configure a slave instance to accept writes or not. Writing against
# a slave instance may be useful to store some ephemeral data (because data
# written on a slave will be easily deleted after resync with the master) but
# may also cause problems if clients are writing to it because of a
# misconfiguration.
#
# Since Redis 2.6 by default slaves are read-only.
#
# Note: read only slaves are not designed to be exposed to untrusted clients
# on the internet. It's just a protection layer against misuse of the instance.
# Still a read only slave exports by default all the administrative commands
# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
# security of read only slaves using 'rename-command' to shadow all the
# administrative / dangerous commands.
slave-read-only no
  • master がダウンして slave のみになった時でも書き込みできるよう slave-read-only no を設定します。

redis2.windows-service.conf

■その1

# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
port 6380
  • port 6379port 6380 に変更します。

■その2

# Specify the log file name. Also 'stdout' can be used to force
# Redis to log on the standard output.
#logfile "Logs/redis_log.txt"
logfile "Logs/redis2_log.txt"
# The filename where to dump the DB
#dbfilename "dump.rdb"
dbfilename "dump2.rdb"
# Master-Slave replication. Use slaveof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# 1) Redis replication is asynchronous, but you can configure a master to
#    stop accepting writes if it appears to be not connected with at least
#    a given number of slaves.
# 2) Redis slaves are able to perform a partial resynchronization with the
#    master if the replication link is lost for a relatively small amount of
#    time. You may want to configure the replication backlog size (see the next
#    sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
#    network partition slaves automatically try to reconnect to masters
#    and resynchronize with them.
#
# slaveof <masterip> <masterport>
slaveof 127.0.0.1 6379
# You can configure a slave instance to accept writes or not. Writing against
# a slave instance may be useful to store some ephemeral data (because data
# written on a slave will be easily deleted after resync with the master) but
# may also cause problems if clients are writing to it because of a
# misconfiguration.
#
# Since Redis 2.6 by default slaves are read-only.
#
# Note: read only slaves are not designed to be exposed to untrusted clients
# on the internet. It's just a protection layer against misuse of the instance.
# Still a read only slave exports by default all the administrative commands
# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
# security of read only slaves using 'rename-command' to shadow all the
# administrative / dangerous commands.
slave-read-only no
  • ログと DB ファイルを別にするので、logfile "Logs/redis2_log.txt"dbfilename "dump2.rdb" を設定します。
  • 6380番ポートで起動する Redis はデフォルトでは slave 側にします。slaveof 127.0.0.1 6379 を設定します。
  • master がダウンして slave のみになった時でも書き込みできるよう slave-read-only no を設定します。

redis-sentinel.windows-service.conf.org

# Specify the log file name. Also 'stdout' can be used to force
# Redis to log on the standard output.
#logfile "Logs/redis_log.txt"
logfile "Logs/redis-sentinel_log.txt"
# The Redis heap must be larger than the value specified by the maxmemory
# flag, as the heap allocator has its own memory requirements and
# fragmentation of the heap is inevitable. If only the maxmemory flag is
# specified, maxheap will be set at 1.5*maxmemory. If the maxheap flag is
# specified along with maxmemory, the maxheap flag will be automatically
# increased if it is smaller than 1.5*maxmemory.
#
# maxheap <bytes>
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 1500
sentinel failover-timeout mymaster 90000
sentinel parallel-syncs mymaster 1
  • logfile "Logs/redis-sentinel_log.txt" に変更します。
  • maxheap 104857600 を削除します。
  • ファイルの最後にレプリケーション構成にしている Redis の設定を追加します。
  • sentinel down-after-milliseconds resque 1500 ( 1.5秒 ) と設定したのですぐに切り替わるはず。。。
  • Redis Sentinel の記事が書いてあるサイトを見た感じでは他の設定を削除しても問題なさそうなのですが、きちんと時間を取って検証しているわけではないため、今回は必要な設定を追加するだけとします。

redis-sentinel1.windows-service.conf, redis-sentinel2.windows-service.conf, redis-sentinel3.windows-service.conf

■redis-sentinel1.windows-service.conf

# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
#port 6379
port 6381
# Specify the log file name. Also 'stdout' can be used to force
# Redis to log on the standard output.
#logfile "Logs/redis_log.txt"
logfile "Logs/redis-sentinel1_log.txt"

■redis-sentinel2.windows-service.conf

# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
#port 6379
port 6382
# Specify the log file name. Also 'stdout' can be used to force
# Redis to log on the standard output.
#logfile "Logs/redis_log.txt"
logfile "Logs/redis-sentinel2_log.txt"

■redis-sentinel3.windows-service.conf

# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
#port 6379
port 6383
# Specify the log file name. Also 'stdout' can be used to force
# Redis to log on the standard output.
#logfile "Logs/redis_log.txt"
logfile "Logs/redis-sentinel3_log.txt"
  • ポート番号とログファイルの設定を変更します。

履歴

2015/07/29
初版発行。
2015/07/30
いろいろ間違いがあることに気づいたので、修正しました。
* 「参照したサイト・書籍」に 7,8,9 を追加しました。
* redis.windows-service.conf の「■その2」で slave-priority 2 を設定するよう記述しましたが、不要なので削除しました。
* redis2.windows-service.conf の「■その2」で slave-priority 4 を設定するよう記述しましたが、不要なので削除しました。
* redis-sentinel.windows-service.conf.org で sentinel monitor resque ... の設定を記述しましたが、mymaster だけで十分 ( slave の情報は master から取得するため ) でしたので、削除しました。
* Redis Sentinel へ接続して info sentinel コマンドを実行した時に master 側のみ認識されている画像へ差し替えました。またその後の redis-sentinel1.windows-service.conf の中身も sentinel monitor mymaster ... だけ書かれているものに差し替えました。