2016/11/28

redis for scala play


scala play 預設是使用 ehcache 來當作 cache 的 library,但這個實作常常會在開發的過程當中,會因為程式自動重載的功能,而造成 cache 出現 The play Cache is not alive (STATUS_SHUTDOWN) 的錯誤訊息,在搜尋過後,了解到這可能是 ehcache 的 bug,因此就嘗試將 ehcache 更換成 redis。


安裝 redis


從開發環境到正式環境,需要在不同作業系統安裝 redis,因此我們在這裡記錄不同作業系統安裝 redis 的方法。


windows

在 windows 安裝 [料理佳餚] 在 Windows 上安裝 Redis


Redis on Windows


要注意 Memory Limit 的設定,不然 redis 應該會把記憶體吃光。


用 telnet 或是 redis-cli 可以測試有沒有裝好。


telnet localhost 6379

Mac

sudo port install redis

sudo port load redis

sudo port unload redis

# start redis manually
redis-server /opt/local/etc/redis.conf

要自己去修改 /opt/local/etc/redis.conf


# limited number of clients in developement environment
maxclients 50

# 限制 redis 最多可使用多少記憶體
maxmemory 500MB

# 當記憶體不夠時,要用什麼方式處理
maxmemory-policy volatile-lru

Debian 8

Dotdeb 是Debian 的 3rd party repository,在裡面選擇 Taiwan mirror site。


vi /etc/apt/sources.list.d/dotdeb.list

deb http://ftp.yzu.edu.tw/Linux/dotdeb/ jessie all
deb-src http://ftp.yzu.edu.tw/Linux/dotdeb/ jessie all

安裝 Dotdeb 的 GPG key


wget https://www.dotdeb.org/dotdeb.gpg
sudo apt-key add dotdeb.gpg

安裝 redis server


sudo apt-get update
sudo apt-get install redis-server

啟動/停止


sudo service redis-server start

sudo service redis-server stop

用 redis-benchmark 測試連線狀況


redis-benchmark -q -n 1000 -c 10 -P 5

調整系統參數


sudo sysctl vm.overcommit_memory=1

vi /etc/sysctl.conf
vm.overcommit_memory = 1

Centos 7

安裝 epel


wget -r --no-parent -A 'epel-release-*.rpm' http://dl.fedoraproject.org/pub/epel/7/x86_64/e/

rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-*.rpm

安裝 redis


yum install redis

啟動/停止 redis


systemctl enable redis.service
systemctl start redis.service

systemctl stop redis.service

cluster

redis cluster 是用 sharding 的方式實作的,每一個節點負責一部分 hash slot,一般要建構 cluster 環境,要用到三個 redis node,再加上備援,應該要 6 個 redis node,另外三個是 slave node。


如果要測試細節可以參考這篇文章: Redis Cluster 3.0搭建與使用


或是直接研究官方的文件 Redis cluster tutorial


redis for play


play-redis 是 Play framework 2 cache plugin as an adapter to redis-server,使用這個 framework 的優勢是實作了 play 的 CacheAPI,因此我們可以透過設定,就將 ehcache 調整為 redis。


首先要在 build.sbt 將 disable ehcache,並加上 play-redis 的 libray。


// enable Play cache API (based on your Play version) and optionally exclude EhCache implementation
libraryDependencies += play.sbt.PlayImport.cache exclude("net.sf.ehcache", "ehcache-core")
// include play-redis library
libraryDependencies += "com.github.karelcemus" %% "play-redis" % "1.3.0-M1"

接下來修改 application.conf


# disable default Play framework cache plugin
play.modules.disabled += "play.api.cache.EhCacheModule"

# enable redis cache module
play.modules.enabled += "play.api.cache.redis.RedisCacheModule"

並在 application.conf 中設定 localhost redis 的連線方式


play.cache {
  // redis for Play https://github.com/KarelCemus/play-redis
  redis {
    redis.host="localhost"
    redis.port=6379

    ##redis-server database, 1-15, default:1
    redis.database=1
    ##connection timeout, default:1s (Duration)
    redis.timeout=1s
    ## Akka actor
    redis.dispatcher="akka.actor.default-dispatcher"
    ## Defines which configuration source enable. Accepted values are static, env, custom
    redis.configuration="static"
    ## optional
    #redis.password="null"
    ## optional, Name of the environment variable with the connection string.
    #redis.connection-string-variable=""
    ## Defines behavior when command execution fails.
    #redis.recovery="log-and-default"
  }
}

透過這樣的設定,就可以在不修改 scala 程式的狀況下,就把 ehcache 改成 redis。