目前Redis实现集群的方法主要是采用一致性哈稀分片(Shard),将不同的key分配到不同的redis server上,达到横向扩展的目的。
对于一致性哈稀分片的算法,Jedis-2.0.0已经提供了,下面是使用示例代码(以ShardedJedisPool为例):
package com.jd.redis.client;

import java.util.ArrayList;

import java.util.List;

import redis.clients.jedis.JedisPoolConfig;

import redis.clients.jedis.JedisShardInfo;

import redis.clients.jedis.ShardedJedis;

import redis.clients.jedis.ShardedJedisPool;

import redis.clients.util.Hashing;

import redis.clients.util.Sharded;

publicclass RedisShardPoolTest {

    static ShardedJedisPoolpool;

    static{

        JedisPoolConfig config =new JedisPoolConfig();//Jedis池配置

        config.setMaxActive(500);//最大活动的对象个数

          config.setMaxIdle(1000 * 60);//对象最大空闲时间

          config.setMaxWait(1000 * 10);//获取对象时最大等待时间

          config.setTestOnBorrow(true);

        String hostA = "10.10.224.44";

          int portA = 6379;

          String hostB = "10.10.224.48";

          int portB = 6379;

        List<JedisShardInfo> jdsInfoList =new ArrayList<JedisShardInfo>(2);

        JedisShardInfo infoA = new JedisShardInfo(hostA, portA);

        infoA.setPassword("redis.360buy");

        JedisShardInfo infoB = new JedisShardInfo(hostB, portB);

        infoB.setPassword("redis.360buy");

        jdsInfoList.add(infoA);

        jdsInfoList.add(infoB);

        pool =new ShardedJedisPool(config, jdsInfoList, Hashing.MURMUR_HASH,

Sharded.DEFAULT_KEY_TAG_PATTERN);

    }

    /**

     * @param args

     */

    publicstaticvoid main(String[] args) {

        for(int i=0; i<100; i++){

            String key = generateKey();

            //key += "{aaa}";

            ShardedJedis jds = null;

            try {

                jds = pool.getResource();

                System.out.println(key+":"+jds.getShard(key).getClient().getHost());

                System.out.println(jds.set(key,"1111111111111111111111111111111"));

            } catch (Exception e) {

                e.printStackTrace();

            }

            finally{

                pool.returnResource(jds);

            }

        }

    }

    privatestaticintindex = 1;

    publicstatic String generateKey(){

        return String.valueOf(Thread.currentThread().getId())+"_"+(index++);

    }

}
 import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; public class Test { /**
* 测试transfer的应用
* @param args
*/
public static void main(String[] args) {
testString(); }
public static void testString() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost",6379); Jedis jedis = pool.getResource();
try {
// 清空数据
System.out.println(jedis.flushDB());
String date = "20131225154209";
String date1 = "20131225154210";
String date2 = "20131225154211";
String date3 = "20131225154212"; HashMap msgMap1=new HashMap();
msgMap1.put("ID", "magid1");
msgMap1.put("Application", "hotelbe");
msgMap1.put("Data", "<OTrequest>reuqeustXML</OTrequest>");
msgMap1.put("DataLength", "200"); Person person = new Person();
person.setAge(BigDecimal.valueOf(23));
person.setName("haijun");
person.setSex("1"); Person person1 = new Person();
person1.setAge(BigDecimal.valueOf(23));
person1.setName("haijun1");
person1.setSex("1"); // 添加数据
byte[] str = SerializeUtil.serialize(person);
byte[] str1 = SerializeUtil.serialize(person1);
jedis.zadd("hotelBE".getBytes(), Double.valueOf(date), str);
jedis.zadd("hotelBE".getBytes(), Double.valueOf(date1), str1);
// jedis.zadd("hotelCE", Double.valueOf(date2), "zset");
// jedis.zadd("hotelCE", Double.valueOf(date3), "zset!");
// 元素个数
System.out.println(jedis.zcard("hotelBE"));
// 获取指定时间的元素
Set<byte[]> set = jedis.zrangeByScore("hotelBE".getBytes(), date.getBytes(), date1.getBytes());
int i=0;
for( Iterator it = set.iterator(); it.hasNext(); )
{
i++;
byte[] persons1 = (byte[]) it.next();
Person person2 = (Person)SerializeUtil.unserialize(persons1);
System.out.println(person2.getName());
}
System.out.println("此时间段内的消息个数为:"+i+"个"); } finally {
// 这里很重要,一旦拿到的jedis实例使用完毕,必须要返还给池中
pool.returnResource(jedis);
}
// 程序关闭时,需要调用关闭方法
pool.destroy(); } public static String getCurrentDateAndTime() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
return sdf.format(new java.util.Date(System.
currentTimeMillis()));
} }
从运行结果中可以看到,不同的key被分配到不同的Redis-Server上去了。
上面的集群模式还存在两个问题:
1.      扩容问题:
因为使用了一致性哈稀进行分片,那么不同的key分布到不同的Redis-Server上,当我们需要扩容时,需要增加机器到分片列表中,这时候会使得同样的key算出来落到跟原来不同的机器上,这样如果要取某一个值,会出现取不到的情况,对于这种情况,Redis的作者提出了一种名为Pre-Sharding的方式:
Pre-Sharding方法是将每一个台物理机上,运行多个不同断口的Redis实例,假如有三个物理机,每个物理机运行三个Redis实际,那么我们的分片列表中实际有9个Redis实例,当我们需要扩容时,增加一台物理机,步骤如下:
A.    在新的物理机上运行Redis-Server;
B.     该Redis-Server从属于(slaveof)分片列表中的某一Redis-Server(假设叫RedisA);
C.     等主从复制(Replication)完成后,将客户端分片列表中RedisA的IP和端口改为新物理机上Redis-Server的IP和端口;
D.    停止RedisA。
这样相当于将某一Redis-Server转移到了一台新机器上。Prd-Sharding实际上是一种在线扩容的办法,但还是很依赖Redis本身的复制功能的,如果主库快照数据文件过大,这个复制的过程也会很久,同时会给主库带来压力。所以做这个拆分的过程最好选择为业务访问低峰时段进行。
2.      单点故障问题:
还是用到Redis主从复制的功能,两台物理主机上分别都运行有Redis-Server,其中一个Redis-Server是另一个的从库,采用双机热备技术,客户端通过虚拟IP访问主库的物理IP,当主库宕机时,切换到从库的物理IP。只是事后修复主库时,应该将之前的从库改为主库(使用命令slaveofno one),主库变为其从库(使命令slaveofIP PORT),这样才能保证修复期间新增数据的一致性
最终部署的情况会是,分布式的每台server 会有一个对应的备机(从机),这样即使有一个分布式的片机挂掉,对应的备机会接管,不会导致因为片机挂掉导致部分数据不能写进或取出的问题

附件是一份windows下redis服务端程序和客户端需要的jar包,附件下载后后缀改为.rar后解压缩
可以自己配置分布式和主从测试,
配置文件着重关注以下配置
服务端口和 绑定网卡IP
# Accept connections on the specified port, default is 6379
port 6178 # If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for connections.
#
# bind 127.0.0.1 是否为备机(IP:端口)
################################# REPLICATION ################################# # Master-Slave replication. Use slaveof to make a Redis instance a copy of
# another Redis server. Note that the configuration is local to the slave
# so for example it is possible to configure the slave to save the DB with a
# different interval, or to listen to another port, and so on.
#
slaveof 127.0.0.1 6378 认证密码
# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the slave to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the slave request.
#

Redis的分布式和主备配置调研的更多相关文章

  1. Ubuntu16.04双网卡主备配置

    前几日写了一篇Ubuntu14.04双网卡主备配置,没成想变化总是这么快,今日安装某软件,提示最匹配的ubuntu版本是16.04,作为一个码农能有什么办法,只能不断去适应变化.拥抱变化. 首先16. ...

  2. keepalived nginx 主备配置

    keepalived  nginx 主备配置(多主多备同理) 1.Nginx服务安装 nginx 不区分主备,在两台服务上安装两个即可. 安装参考:https://www.cnblogs.com/zw ...

  3. MySQL备份与主备配置

    MySQL备份与主备配置 数据备份类型 全量备份:备份整个数据库 增量备份:备份自上一次备份以来(增量或完全)以来变化的数据 差异备份:备份自上一次完全备份以来变化的数据 全量备份 全量备份的方法有 ...

  4. Ubuntu14.04双网卡主备配置

    近日有个需求,交换机有两台,做了堆叠,服务器双网卡,每个分别连到一台交换机上.这样就需要将服务器的网卡做成主备模式,以增加安全性,使得当其中一个交换机不通的时候网卡能够自动切换. 整体配置不难,网上也 ...

  5. mysql主备配置方法

    1. 选择两台机器(这里选的centos6.5 final),安装相同版本的mysql yum install mysql ; yum install mysql-server; 2. 启动mysql ...

  6. mysql主备配置

    目录 mysql主备2 一.master配置:2 1. 修改配置文件 2 2. 登录添加账号并赋权限 2 3. 查看master信息 2 二.slave配置:2 1. 修改配置文件 2 2. 重启登录 ...

  7. Keepalived 主备配置

    keepalived主备或多主多备,配置都是一样配置方法,只是搭建多少的问题. 1.keepalived安装 参考:https://www.cnblogs.com/zwcry/p/9542867.ht ...

  8. Mysql 主备配置

    来自:http://blog.csdn.net/u013256816/article/details/52536283 1. 了解主备配置过程原理. http://blog.csdn.net/u013 ...

  9. Redis(1.13)Redis cluster 分布式集群手动配置

    [1]试验环境 结构图如下: (这里试验没有那么多机器,就用3台机器搭建试验) redis1是redis集群的一个节点A,上面运行了两个redis实例,7001 7004 redis2是redis集群 ...

随机推荐

  1. C++中 =default,=delete用法

    =default: 用于显式要求编译器提供合成版本的四大函数(构造.拷贝.析构.赋值) 例如: class A{ public: A() = default; A(const A& a) = ...

  2. nio原理和示例代码

    我正在为学习大数据打基础中,为了手撸rpc框架,需要懂得nio的原理,在搞懂nio框架前,我会带着大家手撸一些比较底层的代码,当然今后当我们学会了框架,这些繁琐的代码也就不用写了,但是学一学底层的代码 ...

  3. GPS常识-B版(简)

    第一章 绪论 1.简述GPS系统的特点有哪些? 在测绘工程中有如下优点:(1)定位精度高(2)观测时间短(3)测站间无需通视(4)可提供地心坐标(5)操作简便(6)全天候作业(7)功能多.应用广 GP ...

  4. 用Python玩数据-笔记整理-第二章-练习与测试

    课间练习:  经典问题的Python编程 按公式:C= 5/9×(F-32) ,将华氏温度转换成摄氏温度,并产生一张华氏0-300度与对应的摄氏温度之间的对照表(每隔20度输出一次) 验证命题:如果一 ...

  5. py+selenium 自动判断页面是否报错并显示在自动化测试报告【原创】

    有需求就会去研究解决的路子. 现在需求就是,测试报告报错信息一堆,但却无法肉眼看出是什么问题,你只能知道定位不到元素或是超时,但你却不知道其实进入页面就报错了或是提交表单就报错了!也就是看到报错,需要 ...

  6. 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)

    目录 一. 大作业说明 二.基本思路 三.视频纹理表面修复--UV映射 3.1 问题描述 3.2 纹理贴图的基本原理-UV映射 3.3 关键示例代码 四.小结 示例代码托管在:http://www.g ...

  7. python函数知识一 函数初始、定义与调用、返回值、参数和函数的好处+菜中菜

    第四章 函数 1.函数初识: def :关键字 -- 定义 函数名:和变量的定义方式一样 (): 用于参数传递,: 形参:函数的定义中()内的是形参 实参:调用的()内是实参 传参:调用时将实参传递给 ...

  8. CVE-2018-4407 漏洞复现POC

    pip install scapy import scapy from scapy.all import * send(IP(dst="192.168.1.132",options ...

  9. Excel催化剂开源第3波-修复ExcelCom加载项失效问题及WPS可调用Com加载项的方法

    为了还原一个干净无侵扰的网络世界,本文将不进行大规模地分发,若您觉得此文有用,不妨小范围地分享到真正有需要的人手中 功能概述 修复ExcelCom加载项常见问题,如每次需重新勾选COM加载项或COM加 ...

  10. Java-面向对象oop

    在提到面向对象的时候,大多数的书上面介绍的是简短的 类是对象的集合,对象是类的实例化.这样笼统的说法的确可以概括面向对象的思想,但却不能让一个刚入门的人理解到面向对象. 在这里先介绍一下类,当你在Ja ...