Redis官方集群搭建&使用
来源:互联网 发布:主机mac地址怎么查 编辑:程序博客网 时间:2024/06/04 22:41
Redis官方集群设计目标
- 高性能,并且多达1000个节点的线性可扩展性。没有代理,使用异步复制,并且在进行赋值时没有合并操作。
- 可接受程度的写安全:当客户端与大多数master节点建立连接后,系统努力(使用最优的方式)保持来自客户端的写操作。通常有小窗口,其中确认的写操作可能会丢失。当客户端在一个小的分区中,窗口丢失写操作会更大。
- 可用性:Redis集群支持网络分区——其中大部分主节点都可访问,并且不可访问的各master节点对应的从至少一个可访问。而且采用副本迁移,有多个从的主会提供一个从给没有从的主。
Redis集群特点
- Redis集群不为客户端代理重定向服务,需要客户端自己重定向或缓存slot-node映射
- Redis集群是无中心架构
- Redis集群中存在Master-Slave结构
- Redis集群的Re-sharding等管理需要管理员手动触发
几个约束
- Redis版本需要>=3.0
- Redis集群至少需要3个Master节点,考虑到基本的HA,至少需要3个Master节点+3个Slave节点
- 创建集群使用安装Redis官方提供的Ruby实现的工具
- 执行复杂的多键操作, 像set类型的合集或交集的命令,要求键必须是属于同一个节点
- 事务只支持同一个节点的操作,不支持分布式事务
Redis集群示意
一些重要的资料
- Redis集群官方教程(译文)
- Redis集群官方教程(原文)
- Redis集群规范(译文)
- Redis集群规范(原文)
创建Redis集群
在《Redis集群官方教程》中有相当详细的创建集群的方法,这里做一些摘要。
手动方式创建集群
要创建集群,首先需要以集群模式运行的空redis实例。也就说,以普通模式启动的redis是不能作为集群的节点的,需要以集群模式启动的redis实例才能有集群节点的特性、支持集群的指令,成为集群的节点。
下面是最小的redis集群的配置文件:
port 7000cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000appendonly yes
开启集群模式只需打开cluster-enabled配置项即可。每一个redis实例都包含一个配置文件,默认是nodes.conf,用于存储此节点的一些配置信息。这个配置文件由redis集群的节点自行创建和更新,不能由人手动地去修改。
一个最小的集群需要最少3个主节点。第一次测试,强烈建议你配置6个节点:3个主节点和3个从节点。
开始测试,步骤如下:先进入新的目录,以redis实例的端口为目录名,创建目录,我们将在这些目录里运行我们的实例。
类似这样:
mkdir cluster-testcd cluster-testmkdir 7000 7001 7002 7003 7004 7005
在7000-7005的每个目录中创建配置文件redis.conf,内容就用上面的最简配置做模板,注意修改端口号,改为跟目录一致的端口。
把你的redis服务器(用GitHub中的不稳定分支的最新的代码编译来)拷贝到cluster-test目录,然后打开6个终端页准备测试。
在每个终端启动一个redis实例,指令类似这样:
cd 7000../redis-server ./redis.conf
在日志中我们可以看到,由于没有nodes.conf文件不存在,每个节点都给自己一个新的ID。
[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1
这个ID将一直被此节点使用,作为此节点在整个集群中的唯一标识。节点区分其他节点也是通过此ID来标识,而非IP或端口。IP可以改,端口可以改,但此ID不能改,直到这个节点离开集群。这个ID称之为节点ID(Node ID)。
现在6个实例已经运行起来了,我们需要给节点写一些有意义的配置来创建集群。redis集群的命令工具redis-trib可以让我们创建集群变得非常简单。redis-trib是一个用ruby写的脚本,用于给各节点发指令创建集群、检查集群状态或给集群重新分片等。redis-trib在Redis源码的src目录下,需要gem redis来运行redis-trib。
gem install redis
创建集群只需输入指令:
./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
这里用的命令是create,因为我们需要创建一个新的集群。选项”–replicas 1”表示每个主节点需要一个从节点。其他参数就是需要加入这个集群的redis实例的地址。
我们创建的集群有3个主节点和3个从节点。
redis-trib会给你一些配置建议,输入yes表示接受。集群会被配置并彼此连接好,意思是各节点实例被引导彼此通话并最终形成集群。最后,如果一切顺利,会看到类似下面的信息:
[OK] All 16384 slots covered
这表示,16384个哈希槽都被主节点正常服务着。
使用create-cluster脚本创建redis集群
如果你不想像上面那样,单独的手工配置各节点的方式来创建集群,还有一个更简单的系统(当然也没法了解到集群运作的一些细节)。
在utils/create-cluster目录下,有一个名为create-cluster的bash脚本。如果需要启动一个有3个主节点和3个从节点的集群,只需要输入以下指令
1. create-cluster start2. create-cluster create
在步骤2,当redis-trib要你接受集群的布局时,输入”yes”。
现在你可以跟集群交互,第一个节点的起始端口默认是30001。当你完成后,停止集群用如下指令:
1. create-cluster stop.
请查看目录下的README,它有详细的介绍如何使用此脚本。
使用Redis集群
使用命令行方式操作集群请参照《Redis官方文档》,这里主要描述一下在Java代码中如何操作Redis集群。
这里主要介绍两种大家熟悉的工具:Jedis和Spring data redis。
Jedis
Jedis从v2.3.0开始逐步支持Redis官方集群,到目前最新的v2.8.1对集群特性已经支持的相当完善了。考虑到我们一般只使用Redis做简单的缓存,这里只介绍基础应用。
1.添加依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> <type>jar</type> <scope>compile</scope></dependency>
2.创建Jedis集群客户端
public class RedisCluster { static JedisCluster redisCluster = null; public RedisCluster() { if(redisCluster == null) { Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7002)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7003)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7004)); jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7005)); redisCluster = new JedisCluster(jedisClusterNodes); } return; } public JedisCluster getRedisCluster() { return redisCluster; }}
3.操作Jedis集群
public class Application { public static void main(String[] args) { RedisCluster rc = new RedisCluster(); JedisCluster jc = rc.getRedisCluster(); jc.set("foo", "bar"); String value = jc.get("foo"); System.out.printf("\r\nValue is %s", value); }}
4.说明
事实上,由于JedisCluster实现了JedisCommands接口,因此一般操作和使用单点的Redis服务器并无不同。Redis集群的分片、Slot-Node Cach等实现细节,Jedis客户端已经做了很好的封装,很多情况下使用者并无法感知到集群和单点的区别。
另一方面,对于线程安全的考虑,由于JedisCluster对每一个集群节点的连接都保存了一个JedisPool,而JedisPool是线程安全,因此JedisCluster天然线程安全(注:这一点是我主观猜测,网上没有很多讨论JedisCluster线程安全方面的讨论)。
Spring data redis
Spring data redis项目在最新的开发版本1.7.0 RC1中增加了对Redis集群的支持(注意,该版本还未发布,目前还在开发状态),当前的稳定版本1.6.4不支持集群特性。
1.添加依赖
<dependencies> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.4.RELEASE</version> </dependency></dependencies>
2.创建RedisConnectionFactory
集群配置
spring: redis: cluster: nodes: - 127.0.0.1:7000 - 127.0.0.1: 7001 - 127.0.0.1: 7002 - 127.0.0.1: 7003 - 127.0.0.1: 7004 - 127.0.0.1: 7005
3.通过RedisClusterConnection操作集群使用
@Component@ConfigurationProperties(prefix = "spring.redis.cluster")public class ClusterConfigurationProperties { /* * spring.redis.cluster.nodes[0] = 127.0.0.1:7379 * spring.redis.cluster.nodes[1] = 127.0.0.1:7380 * ... */ List<String> nodes; /** * Get initial collection of known cluster nodes in format {@code host:port}. * * @return */ public List<String> getNodes() { return nodes; } public void setNodes(List<String> nodes) { this.nodes = nodes; }}@Configurationpublic class AppConfig { /** * Type safe representation of application.properties */ @Autowired ClusterConfigurationProperties clusterProperties; public @Bean RedisConnectionFactory connectionFactory() { return new JedisConnectionFactory(new RedisClusterConfiguration(clusterProperties.getNodes())); }}@Servicepublic class UseSdr { @Autowired private RedisConnectionFactory connectionFactory; public void test() { RedisClusterConnection connection = connectionFactory.getClusterConnection(); connection.set("a1".getBytes(), "111".getBytes()); connection.set("a2".getBytes(), "222".getBytes()); Set<byte[]> ret = connection.keys("a1".getBytes()); for(byte[] each:ret) { System.out.printf("\r\n" + new String(each)); } }}
4.通过RedisTemplate方式操作集群
RedisTemplate提供了更高层次的抽象,提供了ValueOperations、ListOperations、SetOperations等接口
@Component@ConfigurationProperties(prefix = "spring.redis.cluster")public class ClusterConfigurationProperties { /* * spring.redis.cluster.nodes[0] = 127.0.0.1:7379 * spring.redis.cluster.nodes[1] = 127.0.0.1:7380 * ... */ List<String> nodes; /** * Get initial collection of known cluster nodes in format {@code host:port}. * * @return */ public List<String> getNodes() { return nodes; } public void setNodes(List<String> nodes) { this.nodes = nodes; }}@Configurationpublic class AppConfig { /** * Type safe representation of application.properties */ @Autowired ClusterConfigurationProperties clusterProperties; @Bean public RedisConnectionFactory connectionFactory() { return new JedisConnectionFactory(new RedisClusterConfiguration(clusterProperties.getNodes())); } @Bean @Autowired public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate rt = new RedisTemplate(); rt.setConnectionFactory(redisConnectionFactory); return rt; }}@Servicepublic class UseSdr { @Autowired private RedisTemplate redisTemplate; public void test() { ValueOperations<String, String> valueOp = redisTemplate.opsForValue(); valueOp.set("hello", "world"); String ret = valueOp.get("hello"); System.out.printf("\r\nReturn value is " + ret); }}
- Redis官方集群搭建&使用
- Redis集群搭建使用
- 使用twemproxy搭建redis集群
- Redis集群搭建与使用
- Redis集群搭建和使用
- Redis集群搭建与使用
- redis集群搭建与使用
- Redis集群简单搭建使用
- Redis集群 官方教程
- Redis集群之官方集群
- 自己动手搭建redis集群及使用
- Linux Redis集群搭建与简单使用
- Redis集群搭建与简单使用
- Redis集群搭建与简单使用
- redis-cluser集群搭建及使用
- Redis集群搭建与简单使用
- Redis 集群搭建和简单使用教程
- Redis集群搭建与简单使用
- 异常:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
- Ubuntu安装adb和fastboot
- 一个文件工具类
- http://www.cnblogs.com/JimLy-BUG/p/5274587.html?ref=myread
- C# 图片截取、放大、缩小与保存
- Redis官方集群搭建&使用
- php 学习笔记 -- Cookie 和 Session(六)
- swift 自定义画渐变色折线图
- 关于Spring MVC中注解@@RequestParam参数说明记录
- PHP JSON中文乱码解决方法大全
- 关于linux mmc/sd驱动程序架构
- 程序员常用软件积累
- 简单的NTP客户端实现
- selenium-python自动化测试第一天