1. 程式人生 > >千萬級使用者Redis快取叢集搭建以及專案實戰

千萬級使用者Redis快取叢集搭建以及專案實戰

Redis單機版搭建

3.1安裝redis
?版本說明
本教程使用redis3.0版本。3.0版本主要增加了redis叢集功能。
安裝的前提條件:
需要安裝 gcc:yum install gcc-c++

1、下載redis的原始碼包。
2、把原始碼包上傳到linux伺服器
3、解壓原始碼包
tar -zxvf redis-3.0.0.tar.gz
開啟redis下的目錄直接Make
4、Make
5、Make install
[[email protected] redis-3.0.0]# make install PREFIX=/usr/local/redis

3.2啟動redis
1、前端啟動模式
直接啟動不需要任何配置檔案
/usr/local/redis/bin/redis-server
預設是前端啟動模式,埠是6379
2、後端啟動
1)從redis的原始碼目錄中複製redis.conf到redis的安裝目錄。
2)修改配置檔案
這裡寫圖片描述


3)[[email protected] bin]# ./redis-server redis.conf
R**edis常用命令**
set a 放快取
get a 取key

1,引入Redis jar 如果是Maven需要給他座標
package com.taotao.rest.jedis;

import org.junit.Test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class JedisTest {

@Test
public void testJedisSingle () {
    //測試單機版
    //建立一個jedis物件
    Jedis jedis = new Jedis("192.168.31.123", 6379);
    //host 是IP地址
    //port是埠號
    //呼叫Jedis物件方法,方法名和redis命令保持一致
    //key 和value的形式
            //Set賦值
    jedis.set("key1", "jedis test");
    //get取值
    String string = jedis.get("key1");
    System.out.println(string);
    //關閉jedis
    jedis.close();
}

Jedis連線池
@Test
public void testJedisPool () {
//建立一個jedis連線池
JedisPool pool = new JedisPool(“192.168.31.123”, 6379);
//從jedis連線池中獲取jedis物件
Jedis jedis = pool.getResource();
String string = jedis.get(“key1”);
System.out.println(string);
//關閉jedis
jedis.close();
//關閉兩連線池
pool.close();

}

}
Redis叢集的搭建
叢集中有三個節點的叢集,每個節點有一主一備。需要6臺虛擬機器。
搭建一個偽分散式的叢集,使用6個redis例項來模擬。
搭建叢集需要的環境
Ruby(一種面向物件程式設計的指令碼語言)編輯Ruby,一種簡單快捷的面向物件(面向物件程式 指令碼語言,在20世紀90年代由日本人松本行弘(Yukihiro Matsumoto)開發,遵守GPL協議和Ruby License。它的靈感與特性來自於 Perl、Smalltalk、Eiffel、Ada以及 Lisp 語言。由 Ruby 語言本身還發展出了JRuby(Java平臺)、IronRuby(.NET平臺)等其他平臺的 Ruby 語言替代品。Ruby的作者於1993年2月24日開始編寫Ruby,直至1995年12月才正式公開發佈於fj(新聞組)。因為Perl發音與6月誕生石pearl(珍珠)相同,因此Ruby以7月誕生石ruby(紅寶石)名。具體參考百度

1,搭建叢集需要使用到官方提供的ruby指令碼。
2,需要安裝ruby的環境。
3,安裝ruby
yum install ruby
yum install rubygems

4,redis叢集管理工具redis-trib.rb

[[email protected] ~]# cd redis-3.0.0
[[email protected] redis-3.0.0]# cd src
[[email protected] src]# ll *.rb
-rwxrwxr-x. 1 root root 48141 Apr 1 07:01 redis-trib.rb
[[email protected] src]#
指令碼需要的ruby包:

7,要上傳到linux服務。
8,安裝ruby的包:
gem install redis-3.0.0.gem
[[email protected] ~]# gem install redis-3.0.0.gem
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation for redis-3.0.0…
Installing RDoc documentation for redis-3.0.0…
叢集的搭建
第一步:建立6個redis例項,埠號從7001~7006

第二步:修改redis的配置檔案
1、修改埠號

·

2、開啟cluster-enable前面的註釋。

第三步:把建立叢集的ruby指令碼複製到redis-cluster目錄下。

第四步:啟動6個redis例項
建立一個指令碼來啟動 vim startall.sh
cd redis01
./redis-server redis.conf
cd redis02
./redis-server redis.conf
cd redis03
./redis-server redis.conf
cd redis04
./redis-server redis.conf
cd redis05
./redis-server redis.conf
cd redis06
./redis-server redis.conf
以上分別是 6個redis叢集
第五步:建立叢集。
./redis-trib.rb create –replicas 1 192.168.31.123:7001
192.168.31.123:7002
192.168.31.123:7003
192.168.31.123:7004
192.168.31.123:7005
192.168.31.123:7006
這裡的IP是自己linux本機上的地址
[[email protected] redis-cluster]# ./startall.sh
[[email protected] redis-cluster]# ps aux|grep redis
root 2642 0.2 0.1 33936 1992 pts/1 Sl+ 03:16 0:19 ./redis-server *:6379
root 3783 0.2 0.1 33936 1948 ? Ssl 05:17 0:00 ./redis-server *:7001 [cluster]
root 3785 0.2 0.1 33936 1948 ? Ssl 05:17 0:00 ./redis-server *:7002 [cluster]
root 3787 0.2 0.1 33936 1952 ? Ssl 05:17 0:00 ./redis-server *:7003 [cluster]
root 3795 0.2 0.1 33936 1948 ? Ssl 05:17 0:00 ./redis-server *:7004 [cluster]
root 3797 0.2 0.1 33936 1948 ? Ssl 05:17 0:00 ./redis-server *:7005 [cluster]
root 3803 0.2 0.1 33936 1948 ? Ssl 05:17 0:00 ./redis-server *:7006 [cluster]
root 3809 0.0 0.0 4356 724 pts/3 S+ 05:18 0:00 grep redis
看到上面資訊表示啟動成功
下面此資訊叢集啟動成功

[[email protected] redis-cluster]# ./redis-trib.rb create –replicas 1 192.168.31.123:7001 192.168.31.123:7002 192.168.31.123:7003 192.168.31.123:7004 192.168.31.123:7005 192.168.31.123:7006

Creating cluster
Connecting to node 192.168.31.123:7001: OK
Connecting to node 192.168.31.123:7002: OK
Connecting to node 192.168.31.123:7003: OK
Connecting to node 192.168.31.123:7004: OK
Connecting to node 192.168.31.123:7005: OK
Connecting to node 192.168.31.123:7006: OK
Performing hash slots allocation on 6 nodes…
Using 3 masters:
192.168.31.123:7001
192.168.31.123:7002 這三個是主節點
192.168.31.123:7003
Adding replica 192.168.31.123:7004 to 192.168.31.123:7001
Adding replica 192.168.31.123:7005 to 192.168.31.123:7002 一個主配置一個從
Adding replica 192.168.31.123:7006 to 192.168.31.123:7003
M: f0d92726bbb9d965d251c6b454f0f4270d1a2d7c 192.168.31.123:7001
slots:0-5460 (5461 slots) master 0-5460 是他的槽數
M: 86da4d7c4d51e3d6d9d93aaef26c6b74a6b70595 192.168.31.123:7002
slots:5461-10922 (5462 slots) master 5461-10922 是他的槽數
M: 01d95e8a67f9c582bbd47a256f79fb69e24a2845 192.168.31.123:7003
slots:10923-16383 (5461 slots) master 5461-10922 是他的槽數
S: 7313c2f7e34ff2eeb0977bc07688a95784d3bc1e 192.168.31.123:7004
replicates f0d92726bbb9d965d251c6b454f0f4270d1a2d7c
S: 0b8010f0a2f6da13814e2ea0657eb0c50086435e 192.168.31.123:7005
replicates 86da4d7c4d51e3d6d9d93aaef26c6b74a6b70595
S: b973eb46720b547f0d096ad750766c25261589dd 192.168.31.123:7006
replicates 01d95e8a67f9c582bbd47a256f79fb69e24a2845
Can I set the above configuration? (type ‘yes’ to accept): yes
Nodes configuration updated
Assign a different config epoch to each node
Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join…
Performing Cluster Check (using node 192.168.31.123:7001)
M: f0d92726bbb9d965d251c6b454f0f4270d1a2d7c 192.168.31.123:7001
slots:0-5460 (5461 slots) master
M: 86da4d7c4d51e3d6d9d93aaef26c6b74a6b70595 192.168.31.123:7002
slots:5461-10922 (5462 slots) master
M: 01d95e8a67f9c582bbd47a256f79fb69e24a2845 192.168.31.123:7003
slots:10923-16383 (5461 slots) master

下面是Redis的備用節點
他沒有槽數 因為它上面的資料和主節點上的是一樣

M: 7313c2f7e34ff2eeb0977bc07688a95784d3bc1e 192.168.31.123:7004
slots: (0 slots) master
replicates f0d92726bbb9d965d251c6b454f0f4270d1a2d7c
M: 0b8010f0a2f6da13814e2ea0657eb0c50086435e 192.168.31.123:7005
slots: (0 slots) master
replicates 86da4d7c4d51e3d6d9d93aaef26c6b74a6b70595
M: b973eb46720b547f0d096ad750766c25261589dd 192.168.31.123:7006
slots: (0 slots) master
replicates 01d95e8a67f9c582bbd47a256f79fb69e24a2845
[OK] All nodes agree about slots configuration.

Check for open slots…
Check slots coverage…
[OK] All 16384 slots covered.
[[email protected] redis-cluster]#

Redis的槽數解說
redis-cluster把所有的物理節點對映到[0-16383]slot上,cluster 負責維護node<->slot<->value
Redis 叢集中內建了 16384 個雜湊槽,當需要在 Redis 叢集中放置一個 key-value 時,redis 先對 key 使用 crc16 演算法算出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,redis 會根據節點數量大致均等的將雜湊槽對映到不同的節點

測試叢集

不加 -c

[[email protected] redis-cluster]# redis01/redis-cli -h 192.168.31.123 -p 7002 不加 -c
192.168.25.153:7002> set a 100
(error) MOVED 15495 192.168.25.153:7003 會報錯 找不到節點 出錯 也能連線 但是不好使
192.168.31.123:7002>

加 -c
[[email protected] redis-cluster]# redis01/redis-cli -h 192.168.31.123 -p 7002 -c

drwxr-xr-x. 2 root root 4096 Jan 5 05:25 redis01
drwxr-xr-x. 2 root root 4096 Jan 5 05:25 redis02
drwxr-xr-x. 2 root root 4096 Jan 5 05:25 redis03
drwxr-xr-x. 2 root root 4096 Jan 5 05:25 redis04
drwxr-xr-x. 2 root root 4096 Jan 5 05:25 redis05
drwxr-xr-x. 2 root root 4096 Jan 5 05:25 redis06
-rwxr-xr-x. 1 root root 48141 Jan 5 05:10 redis-trib.rb
-rwxr-xr-x. 1 root root 259 Jan 5 05:16 startall.sh
[[email protected] redis-cluster]# redis01/redis-cli -h 192.168.31.123 -p 7002 -c
192.168.31.123:7002> set a 100 給節點新增值
-> Redirected to slot [15495] located at 192.168.31.123:7003
OK
192.168.31.123:7003>
這種結果表示叢集搭建成功 你ping誰誰給你PONG redis節點之間是自動的

Redis叢集版測試
使用JedisCluster 不需要建立連線池 它自帶連線池
@Test
public void testJedisCluster () {
//建立一個Set集合
HashSet nodes = new HashSet();
//將Redis所有的節點加入到一個集合裡面
//使用HostAndPost 創建出 Host port ip地址和埠號
nodes.add(new HostAndPort(“192.168.31.123”, 7001));
nodes.add(new HostAndPort(“192.168.31.123”, 7002));
nodes.add(new HostAndPort(“192.168.31.123”, 7003));
nodes.add(new HostAndPort(“192.168.31.123”, 7004));
nodes.add(new HostAndPort(“192.168.31.123”, 7005));
nodes.add(new HostAndPort(“192.168.31.123”, 7006));
//把我Rdeis裡的所以節點告訴Cluster
JedisCluster cluster = new JedisCluster(nodes);
cluster.set(“key1”, “1000”);
String string = cluster.get(“key1”);
System.out.println(string);
cluster.close();
}