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;
	}
}

 

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