Redis集群方案及实现 - yfk的专栏        - 博客频道 - CSDN.NET

yfk的专栏

学习&记录&分享

  • 目录视图

  • 摘要视图

  • 订阅

【公告】博客系统优化升级   Unity3D学习,离VR开发还有一步   博乐招募开始啦   虚拟现实,一探究竟   

Redis集群方案及实现

2014-08-30 17:20            43033人阅读             评论(15)             收藏             举报        
本文章已收录于:        
           分类:        
Redis(12)                                            

作者同类文章X

版权声明:本文为博主原创文章,未经博主允许不得转载。

之前做了一个Redis的集群方案,跑了小半年,线上运行的很稳定
差不多可以跟大家分享下经验,前面写了一篇文章 数据在线服务的一些探索经验,可以做为背景阅读

应用

我们的Redis集群主要承担了以下服务:
1. 实时推荐
2. 用户画像
3. 诚信分值服务

集群状况

集群峰值QPS 1W左右,RW响应时间999线在1ms左右
整个集群:
1. Redis节点: 8台物理机;每台128G内存;每台机器上8个instance
2. Sentienl:3台虚拟机

集群方案


Redis Node由一组Redis Instance组成,一组Redis Instatnce可以有一个Master Instance,多个Slave Instance

Redis官方的cluster还在beta版本,参看Redis cluster tutorial
在做调研的时候,曾经特别关注过KeepAlived+VIP 和 Twemproxy
不过最后还是决定基于Redis Sentinel实现一套,整个项目大概在1人/1个半月

整体设计

1. 数据Hash分布在不同的Redis Instatnce上
2. M/S的切换采用Sentinel
3. 写:只会写master Instance,从sentinel获取当前的master Instane
4. 读:从Redis Node中基于权重选取一个Redis Instance读取,失败/超时则轮询其他Instance
5. 通过RPC服务访问,RPC server端封装了Redis客户端,客户端基于jedis开发
6. 批量写/删除:不保证事务

RedisKey

public class RedisKey implements Serializable{private static final long serialVersionUID = 1L;//每个业务不同的familyprivate String family;private String key;......   //物理保存在Redis上的key为经过MurmurHash之后的值private String makeRedisHashKey(){return String.valueOf(MurmurHash.hash64(makeRedisKeyString()));}//ReidsKey由family.key组成private String makeRedisKeyString(){return family +":"+ key;}//返回用户的经过Hash之后RedisKeypublic String getRedisKey(){return makeRedisHashKey();}.....
}

Family的存在时为了避免多个业务key冲突,给每个业务定义自己独立的Faimily
出于性能考虑,参考Redis存储设计,实际保存在Redis上的key为经过hash之后的值

接口

目前支持的接口包括:

public interface RedisUseInterface{/*** 通过RedisKey获取value* * @param redisKey*           redis中的key* @return *           成功返回value,查询不到返回NULL*/public String get(final RedisKey redisKey) throws Exception;/*** 插入<k,v>数据到Redis* * @param redisKey*           the redis key* @param value*           the redis value* @return *           成功返回"OK",插入失败返回NULL*/public String set(final RedisKey redisKey, final String value) throws Exception;/*** 批量写入数据到Redis* * @param redisKeys*           the redis key list* @param values*           the redis value list* @return *           成功返回"OK",插入失败返回NULL*/public String mset(final ArrayList<RedisKey> redisKeys, final ArrayList<String> values) throws Exception;/*** 从Redis中删除一条数据* * @param redisKey*           the redis key* @return *           an integer greater than 0 if one or more keys were removed 0 if none of the specified key existed*/public Long del(RedisKey redisKey) throws Exception;/*** 从Redis中批量删除数据* * @param redisKey*           the redis key* @return *           返回成功删除的数据条数*/public Long del(ArrayList<RedisKey> redisKeys) throws Exception;/*** 插入<k,v>数据到Redis* * @param redisKey*           the redis key* @param value*           the redis value* @return *           成功返回"OK",插入失败返回NULL*/public String setByte(final RedisKey redisKey, final byte[] value) throws Exception;/*** 插入<k,v>数据到Redis* * @param redisKey*           the redis key* @param value*           the redis value* @return *           成功返回"OK",插入失败返回NULL*/public String setByte(final String redisKey, final byte[] value) throws Exception;/*** 通过RedisKey获取value* * @param redisKey*           redis中的key* @return *           成功返回value,查询不到返回NULL*/public byte[] getByte(final RedisKey redisKey) throws Exception;/*** 在指定key上设置超时时间* * @param redisKey*           the redis key* @param seconds*              the expire seconds* @return *           1:success, 0:failed*/public Long expire(RedisKey redisKey, int seconds) throws Exception;
}

写Redis流程

1. 计算Redis Key Hash值
2. 根据Hash值获取Redis Node编号
3. 从sentinel获取Redis Node的Master
4.  写数据到Redis

        //获取写哪个Redis Nodeint slot = getSlot(keyHash);RedisDataNode redisNode =  rdList.get(slot);//写MasterJedisSentinelPool jp = redisNode.getSentinelPool();Jedis je = null;boolean success = true;try {je = jp.getResource();return je.set(key, value);} catch (Exception e) {log.error("Maybe master is down", e);e.printStackTrace();success = false;if (je != null)jp.returnBrokenResource(je);throw e;} finally {if (success && je != null) {jp.returnResource(je);}}

读流程

1. 计算Redis Key Hash值
2. 根据Hash值获取Redis Node编号
3. 根据权重选取一个Redis Instatnce
4.  轮询读

       //获取读哪个Redis Nodeint slot = getSlot(keyHash);RedisDataNode redisNode =  rdList.get(slot);//根据权重选取一个工作Instatnceint rn = redisNode.getWorkInstance();//轮询int cursor = rn;do {         try {JedisPool jp = redisNode.getInstance(cursor).getJp();return getImpl(jp, key);} catch (Exception e) {log.error("Maybe a redis instance is down, slot : [" + slot + "]" + e);e.printStackTrace();cursor = (cursor + 1) % redisNode.getInstanceCount();if(cursor == rn){throw e;}}} while (cursor != rn);

权重计算

初始化的时候,会给每个Redis Instatnce赋一个权重值weight
根据权重获取Redis Instance的代码:

 public int getWorkInstance() {//没有定义weight,则完全随机选取一个redis instanceif(maxWeight == 0){return (int) (Math.random() * RANDOM_SIZE % redisInstanceList.size());}//获取随机数int rand = (int) (Math.random() * RANDOM_SIZE % maxWeight);int sum = 0;//选取Redis Instancefor (int i = 0; i < redisInstanceList.size(); i++) {sum += redisInstanceList.get(i).getWeight();if (rand < sum) {return i;}}return 0;}

  • 14

  • 0

  • 上一篇HBase原子性保证

  • 下一篇Vector Clock理解

我的同类文章

Redis(12)                                
http://blog.csdn.net                        

参考知识库

更多资料请参考:            

猜你在找

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

                   

  • 个人资料
       
   yfkiss
 
                                                         
  • 访问:956842次

  • 积分:10445

  • 等级:            

    积分:10445
  • 排名:第1035名

  • 原创:151篇

  • 转载:6篇

  • 译文:2篇

  • 评论:214条

  • 联系方式

新浪微博:周晓敏_yfk

Mail:zxmever@gmail.com

  • 博客专栏
    Hive应用

文章:23篇

阅读:217029

    网络编程

文章:5篇

阅读:20656

    Hadoop Streaming实战

文章:14篇

阅读:79933

  • 阅读排行
  • Redis集群方案及实现(42960)

  • Linux下多线程查看工具(pstree、ps、pstack)(38544)

  • hive修改表模式(31241)

  • Kafka(二):环境搭建&测试(30631)

  • Hadoop数据传输工具sqoop(28806)

  • Kafka(一):基础(25121)

  • hive数据导入(19647)

  • hive UDF(18999)

  • TcMalloc,A Big Surprise!(18019)

  • Redis Cluster(Redis 3.X)设计要点(17715)

  • 文章搜索
  • 文章分类
  • c/c++(26)

  • hadoop(30)

  • Linux(16)

  • STL(10)

  • Program(22)

  • Design Pattern(14)

  • Architecture(16)

  • 好文转载(5)

  • 开源学习分享(25)

  • 算法&数据结构(11)

  • 工程实践(8)

  • web(4)

  • Redis(13)

  • Android(1)

  • 网络编程(5)

  • 数据仓库(30)

  • 传输(4)

  • 文章存档

2016年07月(1)

2015年12月(1)

2014年10月(2)

2014年08月(1)

2014年07月(1)

2014年06月(1)

2014年05月(2)

2014年04月(1)

2014年03月(3)

2014年01月(2)

2013年12月(5)

2013年11月(1)

2013年10月(1)

2013年09月(2)

2013年08月(1)

2013年07月(1)

2013年06月(1)

2013年05月(1)

2013年04月(1)

2013年03月(2)

2013年02月(2)

2013年01月(2)

2012年12月(2)

2012年11月(2)

2012年10月(5)

2012年09月(2)

2012年08月(7)

2012年07月(6)

2012年06月(1)

2012年05月(3)

2012年04月(6)

2012年03月(3)

2012年02月(13)

2012年01月(5)

2011年12月(5)

2011年11月(9)

2011年10月(10)

2011年09月(8)

2011年08月(7)

2011年07月(6)

2011年06月(10)

2011年05月(16)

2011年04月(2)

  • 推荐文章

    • * 致JavaScript也将征服的物联网世界

    • * 从苏宁电器到卡巴斯基:难忘的三年硕士时光

    • * 作为一名基层管理者如何利用情商管理自己和团队(一)

    • * Android CircleImageView圆形ImageView

    • * 高质量代码的命名法则

转载于:https://www.cnblogs.com/lhdwr/p/5793067.html

Redis集群方案及实现 - yfk的专栏 - 博客频道 - CSDN.NET相关推荐

  1. Redis Primer(1)基于JedisPool的Redis hset并发性能测试 - @钟超 · 技术博客专栏 - 博客频道 - CSDN.NET...

    Redis Primer(1)基于JedisPool的Redis hset并发性能测试 - @钟超 · 技术博客专栏 - 博客频道 - CSDN.NET Redis Primer(1)基于JedisP ...

  2. iOS 热更新方案 - lance的专栏 - 博客频道 - CSDN.NET

    iOS 热更新方案 - lance的专栏 - 博客频道 - CSDN.NET Weex

  3. Redis集群方案,Codis安装测试

    Redis集群方案,Codis安装测试 1,关于豌豆荚开源的Codis Codis是豌豆荚使用Go和C语言开发.以代理的方式实现的一个Redis分布式集群解决方案,且完全兼容Twemproxy.Twe ...

  4. 基于Twemproxy的Redis集群方案

    基于Twemproxy的Redis集群方案 原文地址:http://www.cnblogs.com/haoxinyue/p/redis.html  为了保持方便,愿原博主谅解 概述 由于单台redis ...

  5. Redis - 集群方案

    在开发测试环境中,我们一般搭建Redis的单实例来应对开发测试需求,但是在生产环境,如果对可用性.可靠性要求较高,则需要引入Redis的集群方案.虽然现在各大云平台有提供缓存服务可以直接使用,但了解一 ...

  6. redis集群方案-Twemproxy

    redis集群方案-Twemproxy 1 Twemproxy是什么? Twemproxy是一种代理分片机制,来源于Twitter开源.Twemproxy按照路由规则,转发给后台的各个Redis服务器 ...

  7. Redis集群方案对比:Codis、Twemproxy、Redis Cluster

    为了保证Redis的高可用,主要需要以下几个方面: 数据持久化 主从复制 自动故障恢复 集群化 我们简单理一下这几个方案的特点,以及它们之间的联系. 数据持久化本质上是为了做数据备份,有了数据持久化, ...

  8. Redis 集群方案

    根据一些测试整理出来的一份方案: 1. Redis 性能 对于redis 的一些简单测试,仅供参考: 测试环境:Redhat6.2 , Xeon E5520(4核)*2/8G,1000M网卡 Redi ...

  9. Redis集群方案应该怎么做?都有哪些方案?

    1.codis. 目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 节点数量改变情况下,旧节点数据可恢复到新hash节点. 2.redis cluster3.0自带的集群,特点在 ...

最新文章

  1. Java后端学习路线【哔哩哔哩网站】【Java基础、SSM框架、Maven、Mysql、Idea的使用、Springboot、Sprinfcloud、设计模式】
  2. 计算机控制技术与自动化的关系,计算机控制技术东南大学自动化学院.ppt
  3. SCSS 实用知识汇总
  4. git仓库创建后,由主支变成开发分支
  5. 中秋快乐:数据库的全家福指尖细数识几何?
  6. CentOS下SNMP的安装与使用
  7. java port_Java NonRegisteringDriver.port方法代码示例
  8. 草莓CDMS原创内容分销系统-微信小说平台系统v1.0
  9. 短信sdk:使用阿里云短信sdk
  10. 设计模式23篇(VIP典藏版)
  11. 总结:KPCB中国合伙人周炜
  12. 用户标签的集合——用户画像及其应用
  13. JSAPI 高德地图应用--关键字搜索、POI搜索定位,获取经纬度
  14. 从 MVC 到使用 ASP.NET Core 6.0 的Minimal API
  15. SharePoint文件审批功能设置
  16. 汉芯一号、木兰语言再到天赐OS,国产基础软件十年泣血,梦想何圆?
  17. 廖雪峰python实战(一)
  18. 下列c语言表达式能正确表达ch是空格或者回车的是,c语言上机选择题题及答案...
  19. 百度地图SDK for Android【离线地图】
  20. 基于STM32开发板I²C总线通信协议浅析

热门文章

  1. 三、Linux 开机、重启和用户登录注销
  2. mysql 用户与数据_MySQL经验9-用户和数据安全
  3. 详解在Visual Studio中使用git版本系统 [转]
  4. Enterprise Library v5.0 -- Data Access Application Block 开发向导(3)
  5. Spoonwep破解wep加密无线路由密码
  6. LNMP-Linux下Nginx+MySQL+PHP+phpMyAdmin+eAcelerator一键安装包
  7. Magento教程 6:商店设定与参数
  8. 一分钟解决“仅限中国大陆地区播放”
  9. php 备份数据库 Backup Your MySQL Database Using PHP
  10. Linux Shell高级技巧(三)