redis集羣 redis-cluster

什麼是Redis-Cluster?

        爲何要搭建Redis 集羣。Redis 是在內存中保存數據的,而我們的電腦一般內存都不大,這也就意味着Redis 不適合存儲大數據,適合存儲大數據的是Hadoop 生態系統的Hbase 或者是MogoDB。Redis 更適合處理高併發,一臺設備的存儲能力是很限的,但是多臺設備協同合作,就可以讓內存增大很多倍,這就需要用到集羣。

        Redis 集羣搭建的方式有多種,例如使用客戶端分片、Twemproxy、Codis 等,但從
redis 3.0 之後版本支持redis-cluster 集羣, 它是Redis 官方提出的解決方案,
Redis-Cluster 採用無中心結構,每個節點保存數據和整個集羣狀態,每個節點都和其他所

有節點連接。其redis-cluster 架構圖如下:

        

架構細節:
(1)所有的redis 節點彼此互聯(PING-PONG 機制),內部使用二進制協議優化傳輸速度和帶
寬.

(2)節點的fail 是通過集羣中超過半數的節點檢測失效時才生效.

(3)客戶端與redis 節點直連,不需要中間proxy 層.客戶端不需要連接集羣所有節點,連接

集羣中任何一個可用節點即可

理解分佈存儲機制-槽
(1)redis-cluster 把所有的物理節點映射到[0-16383]slot 上,cluster 負責維護
node<->slot<->value
(2)Redis 集羣中內置了16384 個哈希槽,當需要在Redis 集羣中放置一個key-value 時,
redis 先對key 使用crc16 算法算出一個結果,然後把結果對16384 求餘數,這樣每個key
都會對應一個編號在0-16383 之間的哈希槽,redis 會根據節點數量大致均等的將哈希槽映
射到不同的節點。

(1)選舉過程是集羣中所有master 參與,如果半數以上master 節點與故障節點通信超過(cluster-node-timeout),認爲該節點故障,自動觸發故障轉移操作.
(2)什麼時候整個集羣不可用(cluster_state:fail)?
    a: 如果集羣任意master 掛掉,且當前master 沒有slave.集羣進入fail 狀態,也可以理解成集羣的slot 映射[0-16383]不完成時進入fail 狀態.
    b: 如果集羣超過半數以上master 掛掉,無論是否有slave 集羣進入fail 狀態.


搭建redis-cluster

搭建要求

需要6 臺redis 服務器。搭建僞集羣。
需要6 個redis 實例。
需要運行在不同的端口7001-7006

 準備工作

(1)安裝gcc 【此步省略】

Redis 是c 語言開發的。安裝redis 需要c 語言的編譯環境。如果沒有gcc 需要在線安裝。

yum install gcc-c++

(2)使用yum 命令安裝ruby (我們需要使用ruby 腳本來實現集羣搭建)【此步省略】

yum install ruby
yum install rubygems
(3)將redis 源碼包上傳到linux 系統,解壓redis 源碼包
(4)編譯redis 源碼,進入redis 源碼文件夾
make
看到以下輸出結果,表示編譯成功


(5)創建目錄/usr/local/redis-cluster 目錄, 安裝6 個redis 實例,分別安裝在以下目錄

/usr/local/redis-cluster/redis-1
/usr/local/redis-cluster/redis-2
/usr/local/redis-cluster/redis-3
/usr/local/redis-cluster/redis-4
/usr/local/redis-cluster/redis-5
/usr/local/redis-cluster/redis-6

以第一個redis 實例爲例,命令如下

make install PREFIX=/usr/local/redis-cluster/redis-1

出現此提示表示成功,按此方法安裝其餘5 個redis 實例

(5)複製配置文件將/redis-3.0.0/redis.conf 複製到redis 下的bin 目錄下

[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-1/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-2/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-3/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-4/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-5/bin
[root@localhost redis-3.0.0]# cp redis.conf /usr/local/redis-cluster/redis-6/bin

配置集羣

(1)修改配置文件

修改運行端口爲7001 (7002 7003 .....)


將cluster-enabled yes 前的註釋去掉


(2)啓動每個redis 實例

以第一個實例爲例,命令如下(可以設置爲後臺啓動)

cd /usr/local/redis-cluster/redis-1/bin/

./redis-server redis.conf

把其餘的5 個也啓動起來,然後查看一下是不是都啓動起來了

[root@localhost ~]# ps -ef | grep redis
root 15776 15775 0 08:19 pts/1 00:00:00 ./redis-server *:7001 [cluster]
root 15810 15784 0 08:22 pts/2 00:00:00 ./redis-server *:7002 [cluster]
root 15831 15813 0 08:23 pts/3 00:00:00 ./redis-server *:7003 [cluster]
root 15852 15834 0 08:23 pts/4 00:00:00 ./redis-server *:7004 [cluster]
root 15872 15856 0 08:24 pts/5 00:00:00 ./redis-server *:7005 [cluster]
root 15891 15875 0 08:24 pts/6 00:00:00 ./redis-server *:7006 [cluster]
root 15926 15895 0 08:24 pts/7 00:00:00 grep redis

(3)上傳redis-3.0.0.gem ,安裝ruby 用於搭建redis 集羣的腳本。

(4)使用ruby 腳本搭建集羣。

進入

./redis-trib.rb create --replicas 1 192.168.25.135:7001 192.168.25.135:7002 192.168.25.135:7003
192.168.25.135:7004 192.168.25.135:7005 192.168.25.135:7006

出現下列提示信息


連接redis-cluster

客戶端工具連接

Redis-cli 連接集羣。

redis-cli -p 7004 -c

-c:代表連接的是redis 集羣

測試:


SpringDataRedis 連接

(1)創建SpringDataRedis-ClusterDemo 工程引入依賴

  <!-- 集中定義依賴版本號-->
	<properties>
		<spring.version>4.2.4.RELEASE</spring.version>
	</properties>
 	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
		</dependency>
		<!-- 緩存-->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.8.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			<version>1.7.2.RELEASE</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<!-- java 編譯插件-->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.2</version>
				<configuration>
				<source>1.7</source>
				<target>1.7</target>
				<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>

添加spring 配置文件

applicationContext-redis-cluster.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加載配置屬性文件-->
<context:property-placeholder ignore-unresolvable="true" location="classpath:properties/redis-cluster-config.properties" />

	<bean id="redis-clusterConfiguration" class="org.springframework.data.redis.connection.redis-clusterConfiguration">
		<property name="maxRedirects" value="${redis.maxRedirects}"></property>
			<property name="clusterNodes">
				  <set>
						<bean class="org.springframework.data.redis.connection.redis-clusterNode">
							<constructor-arg name="host" value="${redis.host1}"></constructor-arg>
							<constructor-arg name="port" value="${redis.port1}"></constructor-arg>
						</bean>
						<bean class="org.springframework.data.redis.connection.redis-clusterNode">
							<constructor-arg name="host" value="${redis.host2}"></constructor-arg>
							<constructor-arg name="port" value="${redis.port2}"></constructor-arg>
						</bean>
						<bean class="org.springframework.data.redis.connection.redis-clusterNode">
							<constructor-arg name="host" value="${redis.host3}"></constructor-arg>
							<constructor-arg name="port" value="${redis.port3}"></constructor-arg>
						</bean>
						<bean class="org.springframework.data.redis.connection.redis-clusterNode">
							<constructor-arg name="host" value="${redis.host4}"></constructor-arg>
							<constructor-arg name="port" value="${redis.port4}"></constructor-arg>
						</bean>
						<bean class="org.springframework.data.redis.connection.redis-clusterNode">
							<constructor-arg name="host" value="${redis.host5}"></constructor-arg>
							<constructor-arg name="port" value="${redis.port5}"></constructor-arg>
						</bean>
						<bean class="org.springframework.data.redis.connection.redis-clusterNode">
							<constructor-arg name="host" value="${redis.host6}"></constructor-arg>
							<constructor-arg name="port" value="${redis.port6}"></constructor-arg>
						</bean>
				</set>
		</property>
	</bean>
	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxIdle" value="${redis.maxIdle}" />
		<property name="maxTotal" value="${redis.maxTotal}" />
	</bean>
	<bean id="jeidsConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
		<constructor-arg ref="redis-clusterConfiguration" />
		<constructor-arg ref="jedisPoolConfig" />
	</bean>
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jeidsConnectionFactory" />
	</bean>
</beans>

(4)編寫測試類,測試值的存取

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext-redis-cluster.
xml")
public class TestSet {
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Test
public void testSetValue(){
redisTemplate.boundSetOps("nameset").add("liming");
redisTemplate.boundSetOps("nameset").add("liuhu");
redisTemplate.boundSetOps("nameset").add("zhoujian");
}
@Test
public void testGetValue(){
Set<String> members = redisTemplate.boundSetOps("nameset").members();
System.out.println(members);
}
}















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章