redis(一) Redis單機安裝,redis集羣各種方案配置(codis,rediscluster,sentinel,ApsaraCache),各種模式的Java操作

前言,Redis寫過一篇,雖然自己覺得內容很實用,但是寫的不詳細與清晰,後來自己看也挺費勁。於是這裏重新寫下。

1、Redis單機搭建。單機也很重要,這裏記錄下。

1、官網下載包。我首先使用的2.x搭建單機方便後續完成手動主從與哨兵搭建。

2、環境下載安裝。yum -y install gcc tcl

3、redis包解壓。tar zxvf redis-2.8.18.tar.gz

4、安裝 .make && make /opt/cloudwise/redis install

5、環境變量。 vi /etc/profile 在後面配置中加 export REDIS_PREFIX=/opt/cloudwise/redis

6、服務開啓.。/opt/cloudwise/redis/bin/redis-server

7、Jedis操作單機redis並能插入數據到對應數據庫實例中。

package com.cloudwise.redis;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import redis.clients.jedis.Jedis;

/**
  * jedis單實例  可以哨兵來做ha 但是沒有解決單點瓶頸
  * <p>Title: JedisDaoImpl</p>  
  * <p>Description: </p>  
  * @author back  
  * @date 2019年9月19日
 */
public class JedisDaoImpl implements RedisDao{

	
	private Jedis jedis;
	private int db;
	
	public JedisDaoImpl(int dbNum){
		jedis = new Jedis("192.168.231.131", 6379,1500);
		this.db = dbNum;
		jedis.select(db);
	}
	
	
	@Override
	public boolean isExist(String key) {
		return jedis.exists(key);
	}

	@Override
	public String set(String key, String value) {
		return jedis.set(key, value);
	}

	@Override
	public String get(String key) {
		return jedis.get(key);
	}

	@Override
	public String setex(String key, String value, int seconds) {
		return jedis.setex(key, seconds, value);
	}

	@Override
	public long delete(String key) {
		return jedis.del(key);
	}

	@Override
	public long incr(String key) {
		return jedis.incr(key);
	}

	/**
	 * 測試對應db中寫數據,經測試成功。
	 * @param args
	 */
	public static void main(String[] args) {
		
		ExecutorService execotor = Executors.newFixedThreadPool(2);
		for (int i = 1; i < 3; i++) {
			execotor.execute(new Task(i));
		}
		execotor.shutdown();
	}
}

二、Redis主從。手動切換、哨兵模式兩種。

1)手動切換。

主節點服務:redis-server --port 6380

從節點服務:redis-server --port 6380 --slaveof 192.168.231.131 6380

手動主從成功。

主節點故障時,從節點執行SLAVEOF no one.執行的從節點成爲主節點。

2)哨兵模式。 

內置哨兵命令位置:redis-2.8.18/src/redis-sentinel.將它防置redis設置的環境變量的bin目錄。

找個目錄添加文件,我的目錄爲:~/sentinel/s1.conf

內容爲:port爲當前哨兵端口。cloudwise爲redis集羣名稱,自定義一個即可。後面的ip與端口爲主redis節點地址。最後面的2爲投票數。比如我有三個哨兵節點,當主節點掛掉,從節點有多個,三個哨兵節點投票,如果有兩票在某一從節點上,則該從節點提升爲主節點。
服務開啓:

主節點:redis-server  從節點:redis-server --SLAVEOF 192.168.231.134 6379

redis節點開啓後開啓哨兵。redis-sentinel ~/sentinel/s1.conf

Java 操作哨兵模式:實測好用

package com.cloudwise.redis;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import com.google.common.collect.Sets;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

/**
  * 哨兵模式
  * <p>Title: SentinelPoolRedisDao</p>  
  * <p>Description: </p>  
  * @author back  
  * @date 2019年9月19日
 */
public class SentinelPoolRedisDao implements RedisDao{

	private  JedisSentinelPool pool ;
	private Jedis jedis;

	public SentinelPoolRedisDao(int num){
		pool = JedisAllPoolFactory.getJedisSentinelPool();
		this.jedis = pool.getResource();
		this.jedis.select(num);
	}
	
	@Override
	public boolean isExist(String key) {
		return jedis.exists(key);
	}

	@Override
	public String set(String key, String value) {
		return jedis.set(key, value);
	}

	@Override
	public String get(String key) {
		return jedis.get(key);
	}

	@Override
	public String setex(String key, String value, int seconds) {
		return jedis.setex(key, seconds, value);
	}

	@Override
	public long delete(String key) {
		return jedis.del(key);
	}

	@Override
	public long incr(String key) {
		return jedis.incr(key);
	}

	public static void main(String[] args) {
		
		SentinelPoolRedisDao dao = new SentinelPoolRedisDao(1);
		
		dao.set("cc", "b");
		System.out.println("成功! 拿到value:"+dao.get("cc"));
	}
}

三、各種redis集羣方案配置

1、codis做redis集羣

1),下載codis,我在git上下的3.1 release版本。安裝jdk要求1.8以上。jdk環境變量設置等就不再說了

2),安裝go環境。我安裝的 go1.6.2.linux-amd64 。go環境變量如圖。這裏注意GOPATH是爲codis而設置的,codis的安裝目錄。不設置安裝會報錯。

3)安裝zookeeper集羣。這裏不再介紹。

4)下載的codis安裝包解壓後放入:/opt/cloudwise/codis/src/github.com/CodisLabs/ 目錄下 前面的/opt/cloudwise/codis爲GOPATH中設置的。後面的一定要如此。否則安裝會報錯。正確的路徑如圖所示:

 

5) 在上面的目錄下  yum install autoconf 

6)當前目錄  make

7)config目錄下dashboard.toml  vi /opt/cloudwise/codis/src/github.com/CodisLabs/codis/config/dashboard.toml。coordinator設置zookeeper地址。把原來的filesystem的註釋掉。admin_addr爲本機ip

8)開啓codis組件dashboard進程。nohup ./bin/codis-dashboard --ncpu=1 --config=./config/dashboard.toml --log=dashboard.log –log-level=WARN & 

設置cpu核數 config路徑 log輸出文件與日誌級別。開啓成功則在zookeeper有codis節點。

停止進程:./bin/codis-admin --dashboard=192.168.231.133:18080 --shutdown

9)config目錄下proxy.toml  vi /opt/cloudwise/codis/src/github.com/CodisLabs/codis/config/proxy.toml。設置本地和代理ip 端口

10)開啓codis組件proxy。nohup ./bin/codis-proxy --ncpu=1 --config=./config/proxy.toml --log=proxy.log --log-level=WARN & 

停止進程:./bin/codis-admin --proxy=192.168.231.133:11080 –auth=”” --shutdown

11)此時proxy還沒有添加到集羣。./bin/codis-admin --dashboard=192.168.231.133:18080 –create-proxy -x 192.168.247.133:11080  這個命令添加到集羣。在 proxy.log日誌中能看到效果。

12)啓動redis-server。修改config/redis.conf.redis綁定IP 和保護模式的設置。

13)啓動codis-fe:nohup ./bin/codis-fe --ncpu=1 --log=fe.log --log-level=WARN --zookeeper=192.168.231.135:2181  --listen=192.168.231.133:8080 & 
前一個參數是zk的地址端口,後面一個是fe的地址端口
 

 

各種pool的工廠

package com.cloudwise.redis;

import java.util.Arrays;
import java.util.Set;

import com.google.common.collect.Sets;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
/**
  * 防止重複代碼的 獲取各種pool的工廠
  * <p>Title: JedisAllPoolFactory</p>  
  * <p>Description: </p>  
  * @author back  
  * @date 2019年9月19日
 */
public class JedisAllPoolFactory {

	private static JedisPoolConfig getConfig(){
		JedisPoolConfig config = new JedisPoolConfig();
		//最大連接數
		config.setMaxTotal(30);
		//最大空閒連接數
		config.setMaxIdle(10);
		//每次釋放連接的最大數目
		config.setNumTestsPerEvictionRun(1024);
		// 釋放連接的掃描間隔(毫秒)
		config.setTimeBetweenEvictionRunsMillis(30000);
		//連接最小空閒時間 
		config.setMinEvictableIdleTimeMillis(1800000);
		//連接空閒多久後釋放, 當空閒時間>該值 且 空閒連接>最大空閒連接數 時直接釋放
		config.setSoftMinEvictableIdleTimeMillis(10000);
		//獲取連接時的最大等待毫秒數,小於零:阻塞不確定的時間,默認-1
		config.setMaxWaitMillis(1500);
		//在獲取連接的時候檢查有效性, 默認false
		config.setTestOnBorrow(true);
		//在空閒時檢查有效性, 默認false
		config.setTestWhileIdle(true);
		//連接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true
		config.setBlockWhenExhausted(false);
		
		return config;
	}
	
	/**
	 * 單機的pool
	 * @return
	 */
	public static JedisPool getJedisPool(){
		JedisPoolConfig config = getConfig();
		JedisPool pool = new JedisPool(config, "192.168.231.131", 6379,15000);
		return pool;
	}
	
	public static JedisSentinelPool getJedisSentinelPool(){
		String hosts = "";
		JedisPoolConfig config = getConfig();
		Set<String> sentinels = transferHostsForSentinel(hosts);
		JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, config, 15000);
		return pool;
	}
	
	public static JedisCluster getJedisCluster(){
		String hosts = "192.168.231.131:6379";
		Set<HostAndPort> nodes = transferHostsForJedisCluster(hosts);
		JedisPoolConfig config = getConfig();
		JedisCluster jedisCluster = new JedisCluster(nodes, config);
		return jedisCluster;
	}
	private static Set<HostAndPort> transferHostsForJedisCluster(String hosts){
		Set<HostAndPort> set = Sets.newHashSet();
		Arrays.asList(hosts.split(",")).forEach(host1 -> {
			String[] meta = host1.trim().split(":");
			HostAndPort hostAndPort = new HostAndPort(meta[0].trim(),Integer.parseInt(meta[1].trim()));
			set.add(hostAndPort);
		});
		return set;
	}
	private static Set<String> transferHostsForSentinel(String hosts){
		Set<String> set = Sets.newHashSet(Arrays.asList(
				hosts.split(",")
		));
		return set;
	}
}

 

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