redis总结

Redis高可用与性能优化
本文探讨了Redis作为高可用缓存和消息队列时的可用性需求,介绍了Redis双机高可用方案的设计与实现,包括主备复制机制、keepalived与监控脚本的应用,以及如何通过配置文件和脚本确保数据的一致性和连续性。同时,文章对比了Redis与Memcache的性能,提出了Redis性能优势的原因,并深入讨论了Redis在数据存储、内存管理、VM实现等方面的特点和优化策略。

转载:http://blog.sina.com.cn/s/blog_4a1f59bf0100teiz.html

redis高可用 (来自于:http://www.iteye.com/topic/1108383)

因为redis不仅作为缓存使用,而且也是resque执行异步和定时任务的消息队列,因此对于可用性的要求就比较高,一旦挂掉,所有后台任务就会全部停止,严重影响网站的功能和体验。

但是redis原生的cluster解决方案迟迟不出,去年看redis官网的时候,说是直到今年5月份才可能会有rc放出,所以没办法,只能自己做一个山寨的高可用方案勉强支撑一段时间。

PS:今年5月份的时候我再看,却又拖到“不早于夏末”了。原来不只是XXX说话不算数的。

redis双机高可用的基础,是redis的主备复制机制。指定主备角色,是用slaveof命令。

指定本机为master

Ruby代码    收藏代码
  1. slaveof NO ONE  


指定本机为192.168.1.10的slave
Ruby代码    收藏代码
  1. slaveof 192.168.1.10 6379  


本来一开始我也想如同mysql的master-master机制那样,分别在配置文件中指定本机为对方的slave,不过后来发现这个方法行不 通。如果配置文件中都设置slaveof x.x.x.x,那么这两个redis启动之后不提供服务,客户端无法连接,类似于服务死锁的状态。

经过多次实验发现,如果两个服务按照master-slave的方式启动,然后给master发送slaveof命令,指定其为另一个的slave,则此时双方都为slave,数据可以进行双向同步。基于这个原理,设计了一个redis双机互备的机制。

在自定义的配置文件中,做如下配置:

Ruby代码    收藏代码
  1. redis:  
  2.   server: redis://192.168.1.1:6379  
  3.   cluster:  
  4.     master: redis://192.168.1.10:6379  
  5.     slave: redis://192.168.1.20:6379  


192.168.1.1是keepalived的virtual ip,应用程序只使用这个ip地址来存取redis。

其核心的实现方式如下:

4.1 两台redis服务器,配合keepalived。初始状态,是在master(192.168.1.10)上绑定keepalived的virtual ip 192.168.1.1。
4.2 启动一个监控脚本,每秒钟对两个redis服务进行一次扫描。
4.3 如果两台redis处于正常master-slave状态,则不进行操作。
4.4 如果master挂掉,监控脚本对在线的slave(192.168.1.20)发送slaveof NO ONE命令,设置其为临时的主机temp-master,同时由于原来的master服务器挂掉,virtual ip 192.168.1.1自动转移至temp-master,不影响应用程序对redis的存取。此时应用程序新产生的数据都保存到temp- master(192.168.1.20)上。
4.5 脚本监测到原来的master(192.168.1.10)在挂掉后重新启动加入集群,则向master发送slaveof 192.168.1.20 6379命令,设置其为temp-slave,从temp-master(192.168.1.20)复制在自己挂掉期间丢失的数据。同时virtual ip自动跳回temp-slave(192.168.1.10)向应用程序提供服务。
4.6 延时30秒钟,确保数据复制完毕,对调temp-master和temp-slave的角色,恢复默认的master-slave体系。

我知道延时30秒钟确保数据复制完毕这种方式很不好,但我确实在redis的info命令响应中没有找到指示复制完毕的字段。如果有消息能够明确指出数据复制完毕的状态会更好。

这样,两台redis服务器中的任何一台挂掉,都会由另一台继续提供服务,不会对网站形成可察觉的影响,也不会丢失数据。



该文的url:http://my.oschina.net/victorli/blog/10939
最近在研究 Redis。去年曾做过一个 MemcacheDB, Tokyo Tyrant, Redis performance test, 到目前为止,这个benchmark结果依然有效。这1年我们经历了很多眼花缭乱的key value存储产品的诱惑,从Cassandra的淡出(Twitter暂停在主业务使用)到HBase的兴起(Facebook新的邮箱业务选用 HBase(2)),当再回头再去看Redis,发现这个只有1万多行源代码的程序充满了神奇及大量未经挖掘的特性。Redis性能惊人,国内前十大网站 的子产品估计用1台Redis就可以满足存储及Cache的需求。除了性能印象之外,业界其实普遍对Redis的认识存在一定误区。本文提出一些观点供大 家探讨。

1. Redis是什么

这个问题的结果影响了我们怎么用Redis。如果你认为Redis是一个key value store, 那可能会用它来代替MySQL;如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary Server的缩写,在Redis在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems,这个定义偏向key value store。还有一些看法则认为Redis是一个memory database,因为它的高性能都是基于内存操作的基础。另外一些人则认为Redis是一个data structure server,因为Redis支持复杂的数据特性,比如List, Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。

互联网数据目前基本使用两种方式来存储,关系数据库或者key value。但是这些互联网业务本身并不属于这两种数据类型,比如用户在社会化平台中的关系,它是一个list,如果要用关系数据库存储就需要转换成一种 多行记录的形式,这种形式存在很多冗余数据,每一行需要存储一些重复信息。如果用key value存储则修改和删除比较麻烦,需要将全部数据读出再写入。Redis在内存中设计了各种数据类型,让业务能够高速原子的访问这些数据结构,并且不 需要关心持久存储的问题,从架构上解决了前面两种存储需要走一些弯路的问题。

2. Redis不可能比Memcache快

很多开发者都认为Redis不可能比Memcached快,Memcached完全基于内存,而Redis具有持久化保存特性,即使是异步 的,Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因,目前想到的原因有这几方面。

  • Libevent。 和Memcached不同,Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到 libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event loop(4)。业界不少开发者也建议Redis使用另外一个libevent高性能替代libev,但是作者还是坚持Redis应该小巧并去依赖的思 路。一个印象深刻的细节是编译Redis之前并不需要执行./configure。
  • CAS问题。CAS是Memcached中比较方便的一种防止竞争修改资源的方法。CAS实现需要为每个cache key设置一个隐藏的cas token,cas相当value版本号,每次set会token需要递增,因此带来CPU和内存的双重开销,虽然这些开销很小,但是到单机10G+ cache以及QPS上万之后这些开销就会给双方相对带来一些细微性能差别(5)。

3. 单台Redis的存放数据必须比物理内存小

Redis的数据全部放在内存带来了高速的性能,但是也带来一些不合理之处。比如一个中型网站有100万注册用户,如果这些资料要用Redis来存 储,内存的容量必须能够容纳这100万用户。但是业务实际情况是100万用户只有5万活跃用户,1周来访问过1次的也只有15万用户,因此全部100万用 户的数据都放在内存有不合理之处,RAM需要为冷数据买单。

这跟操作系统非常相似,操作系统所有应用访问的数据都在内存,但是如果物理内存容纳不下新的数据,操作系统会智能将部分长期没有访问的数据交换到磁盘,为新的应用留出空间。现代操作系统给应用提供的并不是物理内存,而是虚拟内存(Virtual Memory)的概念。

基于相同的考虑,Redis 2.0也增加了VM特性。让Redis数据容量突破了物理内存的限制。并实现了数据冷热分离。

4. Redis的VM实现是重复造轮子

Redis的VM依照之前的epoll实现思路依旧是自己实现。但是在前面操作系统的介绍提到OS也可以自动帮程序实现冷热数据分离,Redis只 需要OS申请一块大内存,OS会自动将热数据放入物理内存,冷数据交换到硬盘,另外一个知名的“理解了现代操作系统(3)”的Varnish就是这样实 现,也取得了非常成功的效果。

作者antirez在解释为什么要自己实现VM中提到几个原因(6)。主要OS的VM换入换出是基于Page概念,比如OS VM1个Page是4K, 4K中只要还有一个元素即使只有1个字节被访问,这个页也不会被SWAP, 换入也同样道理,读到一个字节可能会换入4K无用的内存。而Redis自己实现则可以达到控制换入的粒度。另外访问操作系统SWAP内存区域时block 进程,也是导致Redis要自己实现VM原因之一。

5. 用get/set方式使用Redis

作为一个key value存在,很多开发者自然的使用set/get方式来使用Redis,实际上这并不是最优化的使用方法。尤其在未启用VM情况下,Redis全部数据需要放入内存,节约内存尤其重要。

假如一个key-value单元需要最小占用512字节,即使只存一个字节也占了512字节。这时候就有一个设计模式,可以把key复用,几个key-value放入一个key中,value再作为一个set存入,这样同样512字节就会存放10-100倍的容量。

这就是为了节约内存,建议使用hashset而不是set/get的方式来使用Redis,详细方法见参考文献(7)。

6. 使用aof代替snapshot

Redis有两种存储方式,默认是snapshot方式,实现方法是定时将内存的快照(snapshot)持久化到硬盘,这种方法缺点是持久化之后 如果出现crash则会丢失一段数据。因此在完美主义者的推动下作者增加了aof方式。aof即append only mode,在写入内存数据的同时将操作命令保存到日志文件,在一个并发更改上万的系统中,命令日志是一个非常庞大的数据,管理维护成本非常高,恢复重建时 间会非常长,这样导致失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型,所有的优势都是建立在对内存复杂数据结构高效的原子操作 上,这样就看出aof是一个非常不协调的部分。

其实aof目的主要是数据可靠性及高可用性,在Redis中有另外一种方法来达到目的:Replication。由于Redis的高性能,复制基本没有延迟。这样达到了防止单点故障及实现了高可用。

小结

要想成功使用一种产品,我们需要深入了解它的特性。Redis性能突出,如果能够熟练的驾驭,对国内很多大型应用具有很大帮助。希望更多同行加入到Redis使用及代码研究行列。



### Redis 实训总结与经验分享 Redis 是一种高性能的内存数据库,广泛应用于缓存、消息队列、分布式锁等场景。以下是对 Redis 实训中关键点的总结和经验分享。 #### 1. Redis 的安全问题 在实际项目中,Redis 的安全性是一个不可忽视的问题。如果配置不当,可能会导致数据泄露、拒绝服务攻击或数据篡改等问题[^1]。因此,在使用 Redis 时需要特别注意以下几点: - **访问控制**:通过设置密码(`requirepass` 配置项)限制对 Redis 服务器的访问。 - **限流防护**:启用 Redis 的限流机制,防止恶意请求导致的服务中断。 - **数据加密**:对于敏感数据,可以采用数据加密技术确保其完整性。 #### 2. Redis 的性能优化 Redis 的高性能主要得益于其基于内存的操作模式以及简单的键值存储结构。在实际应用中,可以通过以下方式进一步提升 Redis 的性能[^2]: - **缓存策略**:将热点数据存储Redis 中,减少对后端数据库(如 MySQL)的直接访问压力。例如,让 80% 以上的查询走缓存,20% 以下的查询走数据库。 - **持久化配置**:根据业务需求选择合适的持久化方式(RDB 或 AOF)。RDB 提供快照式持久化,适合数据恢复;AOF 提供更高的数据安全性,但可能会影响性能。 - **分片与集群**:当单机 Redis 的容量或性能无法满足需求时,可以考虑使用 Redis 分片或 Redis 集群来扩展存储能力和并发处理能力。 #### 3. Redis 的备份与恢复 为了确保数据的安全性和可靠性,定期进行 Redis 数据备份是非常重要的[^1]。以下是备份与恢复的最佳实践: - **自动备份**:通过配置定时任务(如 `cron`)定期生成 RDB 文件。 - **增量备份**:结合 AOF 日志实现增量备份,减少全量备份带来的性能开销。 - **灾难恢复**:在主从架构中,确保从节点的数据同步正常,以便在主节点故障时快速切换。 #### 4. 权限管理与可视化范围 在某些项目中,Redis 的数据可能需要根据不同角色的权限进行访问控制。例如,在一个微信小程序开发项目中,不同用户角色可以查看不同的数据范围[^3]。类似地,可以在 Redis 中实现类似的权限管理逻辑: - **命名空间隔离**:为不同角色的数据设置独立的命名空间前缀,避免数据冲突。 - **ACL 控制**:Redis 6.0 及以上版本支持 ACL(Access Control List),可以为不同用户分配特定的命令权限和键空间访问权限。 #### 5. Maven 项目中的 Redis 集成 在基于 Maven 的 Spring Boot 项目中集成 Redis 时,可以通过以下步骤完成配置[^4]: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 同时,需要在 `application.yml` 或 `application.properties` 文件中配置 Redis 连接信息: ```yaml spring: redis: host: localhost port: 6379 password: your_password timeout: 5000ms lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0 ``` #### 6. 常见问题与解决方法 在 Redis 实训过程中,可能会遇到以下常见问题: - **内存不足**:可以通过调整 `maxmemory` 和 `maxmemory-policy` 参数来解决。 - **网络延迟**:检查 Redis 服务器与客户端之间的网络连接是否正常。 - **数据丢失**:确保持久化配置正确,并定期测试数据恢复流程。 --- ### 示例代码:Redis 缓存操作 以下是一个简单的 Redis 缓存操作示例: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @Service public class CacheService { @Autowired private StringRedisTemplate redisTemplate; public void setCache(String key, String value) { redisTemplate.opsForValue().set(key, value); } public String getCache(String key) { return redisTemplate.opsForValue().get(key); } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值