定義
redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步
正文
Redis安裝
- 首先需要安裝gcc:yum install gcc-c++
- 下載redis的源碼包
- 上傳源碼包到linux服務器
- 解壓壓縮包:tar -zxvf redis-3.0.0.tar.gz
- 進入到redis解壓後的目錄 make
- make install [root@bogon redis-3.0.0]# make installPREFIX=/usr/local/redis
Redis啓動
- 前端啓動(默認是前端啓動,端口6379) /usr/local/redis/bin/redis-server
- 後端啓動 首先從redis的源碼目錄中複製redis.conf到redis的安裝目錄,然後修改配置文件
[root@bogonbin]# ./redis-server redis.conf
Redis集羣的搭建
redis-cluster架構圖
redis-cluster把所有的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->value
Redis 集羣中內置了 16384 個哈希槽,當需要在 Redis 集羣中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量大致均等的將哈希槽映射到不同的節點
redis-cluster投票:容錯
- 領着投票過程是集羣中所有master參與,如果半數以上master節點與master節點通信超過(cluster-node-timeout),認爲當前master節點掛掉
- 什麼時候整個集羣不可用(cluster_state:fail)?
第一 種情況 如果集羣任意master掛掉,且當前master沒有slave.集羣進入fail狀態,也可以理解成集羣的slot映射[0-16383]不完成時進入fail狀態. ps : redis-3.0.0.rc1加入cluster-require-full-coverage參數,默認關閉,打開集羣兼容部分失敗 第二種情況 如果集羣超過半數以上master掛掉,無論是否有slave集羣進入fail狀態
案例:Redis集羣演示
集羣結構
集羣中有三個節點的集羣,每個節點有一主一備。需要6臺虛擬機。搭建一個僞分佈式的集羣,使用6個redis實例來模擬。
所需環境
搭建集羣需要使用到官方提供的ruby腳本。
需要安裝ruby的環境
安裝Ruby
yum install ruby
yum install rubygems
腳本需要ruby的包:[root@bogon ~]# gem install redis-3.0.0.gem (下載地址:https://rubygems.org/gems/redis/)
集羣的搭建
第一步:創建6個redis實例,端口號從7001~7006(創建時請務必清空數據庫 flushall )
redis-trib.rb在redis解壓包的src目錄下,需要拷貝過來
shutdownAll.sh爲啓動這6個redis實例的腳本,要不太麻煩
startAll.sh
創建腳本的命令就是vim 一個文件的名稱,然後chmod +x 這個文件
第二步:修改端口號
打開cluster-enable前面的註釋
第三步:把創建集羣的ruby腳本複製到redis-cluster目錄下。
第四步:啓動6個redis實例
第五步:創建集羣。
./redis-trib.rb create --replicas 1 192.168.2.100:7001 192.168.2.100:7002 192.168.2.100:7003 192.168.2.100:7004 192.168.2.100:7005 192.168.2.100:7006 |
添加成功頁面
第六步:測試 ./redis01/redis-cli -h 192.168.2.100 -p 7001 -c。注意一定要加上-c 否則會get值的時候會報錯。
第七步:關閉 ./shutdownAll.sh
redis整合spring
單機版
配置文件
<!-- redis配置 -->
<!-- 加載配置文件 -->
<context:property-placeholder location="classpath:properties/*.properties" />
<!-- 連接池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大連接數 -->
<property name="maxTotal" value="30" />
<!-- 最大空閒連接數 -->
<property name="maxIdle" value="10" />
<!-- 每次釋放連接的最大數目 -->
<property name="numTestsPerEvictionRun" value="1024" />
<!-- 釋放連接的掃描間隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- 連接最小空閒時間 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 連接空閒多久後釋放, 當空閒時間>該值 且 空閒連接>最大空閒連接數 時直接釋放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 獲取連接時的最大等待毫秒數,小於零:阻塞不確定的時間,默認-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在獲取連接的時候檢查有效性, 默認false -->
<property name="testOnBorrow" value="true" />
<!-- 在空閒時檢查有效性, 默認false -->
<property name="testWhileIdle" value="true" />
<!-- 連接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true -->
<property name="blockWhenExhausted" value="false" />
</bean>
<!-- 單機版 -->
<bean id="redisClient" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="192.168.2.100"></constructor-arg>
<constructor-arg name="port" value="6379"></constructor-arg>
<constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
</bean>
測試方法
@Test
public void testSpringJedisSingle() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
JedisPool pool = (JedisPool) applicationContext.getBean("redisClient");
Jedis jedis = pool.getResource();
jedis.set("a", "100");
String string = jedis.get("a");
System.out.println(string);
jedis.close();
pool.close();
}
集羣版
配置文件
<!-- redis配置 -->
<!-- 加載配置文件 -->
<context:property-placeholder location="classpath:properties/*.properties" />
<!-- 連接池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大連接數 -->
<property name="maxTotal" value="30" />
<!-- 最大空閒連接數 -->
<property name="maxIdle" value="10" />
<!-- 每次釋放連接的最大數目 -->
<property name="numTestsPerEvictionRun" value="1024" />
<!-- 釋放連接的掃描間隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- 連接最小空閒時間 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 連接空閒多久後釋放, 當空閒時間>該值 且 空閒連接>最大空閒連接數 時直接釋放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 獲取連接時的最大等待毫秒數,小於零:阻塞不確定的時間,默認-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在獲取連接的時候檢查有效性, 默認false -->
<property name="testOnBorrow" value="true" />
<!-- 在空閒時檢查有效性, 默認false -->
<property name="testWhileIdle" value="true" />
<!-- 連接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true -->
<property name="blockWhenExhausted" value="false" />
</bean>
<!-- 集羣版 -->
<bean id="redisClient" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.2.100"></constructor-arg>
<constructor-arg name="port" value="7001"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.2.100"></constructor-arg>
<constructor-arg name="port" value="7002"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.2.100"></constructor-arg>
<constructor-arg name="port" value="7003"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.2.100"></constructor-arg>
<constructor-arg name="port" value="7004"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.2.100"></constructor-arg>
<constructor-arg name="port" value="7005"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.2.100"></constructor-arg>
<constructor-arg name="port" value="7006"></constructor-arg>
</bean>
</set>
</constructor-arg>
<constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
</bean>
測試方法@Test
public void testSpringJedisCluster() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
JedisCluster jedisCluster = (JedisCluster) applicationContext.getBean("redisClient");
jedisCluster.set("a", "100");
String string = jedisCluster.get("a");
System.out.println(string);
jedisCluster.close();
}
注意:測試的時候注意要開放防火牆端口!