本文搭建redis3.0版本,3.0主要增長了redis集羣功能。java
download.redis.io/releases/re… 將下載文件拷貝到/usr/localnode
tar -zxvf redis-3.0.0.tar.gz
複製代碼
cd /usr/local/redis-3.0.0
make
複製代碼
cd /usr/local/redis-3.0.0
make PREFIX=/usr/local/redis install
複製代碼
cd /usr/local/redis
mkdir conf
cp /usr/local/redis-3.0.0/redis.conf /usr/local/redis/bin
複製代碼
daemonize yes
複製代碼
cd /usr/local/redis ./bin/redis-server ./redis.conf //在何處啓動的server,一些配置文件就默認在該處生成(若是配置的相對路徑)
複製代碼
port 7001 //監聽的端口
# bind 127.0.0.1 //綁定ip,只容許該ip訪問,不填默認爲*,表示容許全部ip訪問
requirepass "你的密碼" //開啓密碼
loglevel debug //日誌級別,開發模式儘可能選用debug
logfile "redis.log" //日誌文件路徑,此處使用相對路徑,將生成到/usr/local/redis下
maxmemory 100000000 //容許最大內存佔用100m
appendonly yes //啓用aof
auto-aof-rewrite-percentage 80 //部署在同一機器的多個redis實例,建議把auto-aof-rewrite錯開(可分別寫80-100不等),防止瞬間fork,全部redis進程作rewrite,佔用大量內存
複製代碼
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.0</version>
</dependency>
複製代碼
鏈接池整合spring:redis
<!-- redis鏈接池(單例) -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="close">
<constructor-arg name="poolConfig" ref="jedisPoolConfig"/>
<constructor-arg name="host" value="${redis.host}"/>
<constructor-arg name="port" value="${redis.port}"/>
<constructor-arg name="timeout" value="${redis.timeout}"/>
<constructor-arg name="password" value="${redis.pass}"/>
</bean>
<!--redis配置文件-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大鏈接數 -->
<property name="maxTotal" value="150" />
<!-- 最大空閒鏈接數 -->
<property name="maxIdle" value="30" />
<!-- 最小空閒鏈接數 -->
<property name="minIdle" value="10" />
<!-- 獲取鏈接時的最大等待毫秒數,小於零:阻塞不肯定的時間,默認-1 -->
<property name="maxWaitMillis" value="3000" />
<!-- 每次釋放鏈接的最大數目 -->
<property name="numTestsPerEvictionRun" value="100" />
<!-- 釋放鏈接的掃描間隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="3000" />
<!-- 鏈接最小空閒時間 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 鏈接空閒多久後釋放, 當空閒時間>該值 且 空閒鏈接>最大空閒鏈接數 時直接釋放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 在獲取鏈接的時候檢查有效性, 默認false -->
<property name="testOnBorrow" value="true" />
<!-- 在空閒時檢查有效性, 默認false -->
<property name="testWhileIdle" value="true" />
<!-- 在歸還給pool時,是否提早進行validate操做 -->
<property name="testOnReturn" value="true" />
<!-- 鏈接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true -->
<property name="blockWhenExhausted" value="false" />
</bean>
複製代碼
測試:spring
@RunWith(SpringJUnit4ClassRunner.class) // 指定測試用例的運行器 這裏是指定了Junit4
@ContextConfiguration("classpath:spring/application*.xml")
public class RedisTest {
@Autowired
private JedisPool pool;
@Test
public void testJedisPool() {
Jedis jedis = null;
String name = null;
try {
jedis = pool.getResource();
jedis.set("testName", "RCL");
name = jedis.get("testName");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (jedis != null) {
// 返回給池
jedis.close();
}
Assert.assertEquals("RCL", name);
}
}
複製代碼
若是鏈接不上,可查看是否防火牆沒有將redis端口開放,/etc/sysconfig/iptables添加:後端
-A INPUT -p tcp -m state --state NEW -m tcp --dport 7001 -j ACCEPT //7001即redis端口
複製代碼
而後重啓防火牆。ruby
集羣管理工具redis-trib.rb依賴ruby環境 (1)安裝ruby:bash
yum install ruby yum install rubygems
複製代碼
(2)安裝ruby和redis的接口程序: 拷貝redis-3.0.0.gem至/usr/local。執行:app
gem install /usr/local/redis-3.0.0.gem
複製代碼
(1)創建存放redis羣的文件夾及子文件夾(用於存放每一個redis實例):socket
cd /usr/local
mkdir redis-cluster
mkdir redis-cluster/7001
mkdir redis-cluster/7002
……
複製代碼
(2)將剛剛安裝的單機redis的/usr/local/redis文件夾拷貝到每一個700X文件夾下,(這裏咱們創建六個實例,三主三從)tcp
(3)修改每一個700X目錄下的redis.conf配置文件:
port 700X //各自監聽的端口
#bind 127.0.0.1 //這裏不綁定,默認容許全部ip訪問,或者bind 0.0.0.0
cluster-enabled yes //開啓集羣
cluster-node-timeout 15000 //15時間內沒有收到對方的回覆,則單方面認爲端節點掛掉
複製代碼
另外,因爲下面咱們須要配置集羣密碼,故以前配置的 requirepass 先刪掉,集羣成功後再進行配置。
分別進入700一、700二、...7006目錄,執行:
./redis-server ./redis.conf
複製代碼
/usr/local/redis-cluster/redis-trib.rb create --replicas 1 [ip]:7001 [ip]:7002 [ip]:7003 [ip]:7004 [ip]:7005 [ip]:7006
複製代碼
注意: (1)爲保證遠程可訪問,這裏的ip儘可能使用公網ip,且建立集羣時可先關閉防火牆,不然能夠出現一直join……的現象。
(2)redis集羣至少須要3個主節點,每一個主節點有一個從節點總共6個節點
(3)replicas指定爲1表示每一個主節點有一個從節點
(4)若是出現[ERR] Sorry, can't connect to node
錯誤:
- ruby 和rubygem 版本過低,安裝新版本。查看gem版本和redis版本(redis-cli -v可查看redis版本)
(5)若是出現[ERR] Node 127.0.0.1:7005 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
: 表示集羣時,以前的redis已有數據,那麼登陸到7005的redis中,執行FLUSHALL便可
(6)若是出現ERR Slot 0 is already busy (Redis::CommandError)
: 用redis-cli登陸到每一個節點執行flushall和cluster reset便可2.6進入集羣:
./redis-cli -c -p 7001 -h 123.123.123.123(-c即-cluster 表示進入集羣模式,不加表示進入單機redis)
複製代碼
進入集羣后,鍵入cluster info
,顯示cluster_state:ok
,表示成功
(1)登陸到每一個節點,執行:
config set masterauth [你的密碼] config set requirepass [你的密碼]
複製代碼
(2)隨後登入 7001/bin/redis-cli -c -h 112.74.55.239 -p 7004 -a 你的密碼,執行: config rewrite
(3)防火牆開放7001到7006端口,以及redis總線:17001到17006:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 7001:7006 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 17001:17006 -j ACCEPT
複製代碼
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version> //2.9.0才支持cluster密碼認證,以前版本的jedisCluster.auth("密碼")方法裏面什麼都沒有實現,僅僅拋一個JedisClusterException("No way to dispatch this command to Redis Cluster.")
</dependency>
複製代碼
整合spring:
<!-- redis集羣 -->
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg index="0">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="${redis.host}"></constructor-arg>
<constructor-arg index="1" value="${redis.port1}"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="${redis.host}"></constructor-arg>
<constructor-arg index="1" value="${redis.port2}"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="${redis.host}"></constructor-arg>
<constructor-arg index="1" value="${redis.port3}"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="${redis.host}"></constructor-arg>
<constructor-arg index="1" value="${redis.port4}"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="${redis.host}"></constructor-arg>
<constructor-arg index="1" value="${redis.port5}"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="${redis.host}"></constructor-arg>
<constructor-arg index="1" value="${redis.port6}"></constructor-arg>
</bean>
</set>
</constructor-arg>
<constructor-arg index="1" value="${redis.timeout}"></constructor-arg>
<constructor-arg index="2" value="${redis.sockettimeout}"></constructor-arg>
<constructor-arg index="3" value="${redis.maxAttempts}"></constructor-arg>
<constructor-arg index="4" value="${redis.pass}"></constructor-arg>
<constructor-arg index="5" ref="jedisPoolConfig"></constructor-arg>
</bean>
複製代碼
測試:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/application*.xml")
public class RedisTest {
@Autowired
private JedisCluster jCluster;
@Test
public void testJCluster() {
jCluster.set("name", "RCL");
String name = jCluster.get("testName");
Assert.assertEquals("RCL", name);
}
複製代碼