`
OneAPM_Official
  • 浏览: 25123 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring Data Redis 让 NoSQL 快如闪电 (1)

    博客分类:
  • java
阅读更多

【编者按】本文作者为 Xinyu Liu,详细介绍了 Redis 的特性,并辅之以丰富的用例。在本文的第一部分,将重点概述 Redis 的方方面面。文章系国内 ITOM 管理平台OneAPM 编译呈现。

建立在 Java 企业版之上的多层体系结构是强大的服务器端编程解决方案。作为一名从业多年的 Java 企业版开发人员,我最满意的就是三层企业开发法:最下方是 JPA/Hibernate 持久层,中间是 Spring 或 EJB 应用层,最上方则是 web 层。对于较为复杂的用例,我用 BPM(业务流程管理)、一个类似于 Drools 的规则引擎和一个集成框架(例如 Camel)集成了一个工作流驱动的解决方案。

但是,笔者最近接到一个任务,要设计一个拥有亚秒级响应延迟并能支持成千上万名并发用户的系统。我立即发现了自己常用的 Java 企业版栈区的局限性。基于关系数据库管理系统的传统型 web 应用程序,包括在 Hibernate/JPA 之上构建的应用程序,都有二阶延迟,扩展效果不佳。传统的 Java 企业版持久性体系结构无法满足我当时设计的系统的性能和处理能力要求。然后我转而尝试 NoSQL,最后发现了 Redis

作为一种内存键值数据库,Redis 打破了数据库的传统定义(将数据保存在硬盘上)。反之,使用 Redis 时可结合持久性的 NoSQL 数据库,比如 MongoDB、HBase、Cassandra 或 DynamoDB。Redis 以远程缓存服务器见长,对易挥发数据来说是极快型数据库。

在本文中,笔者会介绍一些有关 Redis 的简单用例和进阶用例以及性能调优情况。当然,我还会做个简单概述,但我相信各位基本都了解 NoSQL 及其各种解决方案

Spring Data Redis

Redis 几乎拥有针对所有编程语言的各种客户端库,其中就包括 Java。Jedis 可能是最受欢迎的 Java 客户端库了。本文中的示例都基于 Spring Data Redis,我把它作为一个较高层次的包装程序 API。Spring Data Redis 不仅配置方便,而且拥有各种友好的 API 和实用插件。

 

Redis 概述

和大多数 NoSQL 数据库一样,Redis 舍弃了表格、行列的关系概念。而事实上,Redis 是一种键值数据库,利用独特的字符串键值来存储和检索每条记录。Redis 支持把以下内置数据结构作为所有记录的值:

  • STRING 保有单个字符串值。

  • LISTSET 和 HASH 从语义上来说与 Java 中的相同数据结构相一致。

  • ZSET 是由浮点分数安排的字符串列表,类似于 Java 中的 PriorityQueue

不同于关系数据库管理系统中的表,Redis 数据结构是即时实例化的。如果用户查询的内容不存在于 Redis 中,系统只会返回空值。虽然 Redis 不允许嵌套结构,但用户可以执行自定义的 Java 或 JSON 串行器/解串器,从而将 POJO 映射到字符串。通过这种方式,就可以把任意 Java bean 保存为 STRING,或者将其放置在 LISTSET 中,等等。

 

性能和可扩展性

对于 Redis,人们注意到的第一个特点可能就是它的速度极快。根据记录的大小和连接的数量,性能基准会有所不同,但延迟通常为单数位毫秒。在大多数用例中,Redis 每秒最多可支持 50000 次请求。如果用户使用较高端的硬件,处理能力更可高达每秒 700000 次请求(但这一数值可能会被网卡带宽扼制)。

作为一种内存数据库,Redis 的存储容量有限; AWS EC2 中的最大实例为 r3.8xlarge,内存 244 GB。由于数据结构的索引和性能都经过优化,Redis 消耗的内存比所存储的数据量大得多。切分 Redis 有助于克服这一局限性。要把内存数据备份到硬盘上,可以在预定作业中进行时间点转储,也可以根据需要运行 dump 命令。

 

用 Spring 进行远程数据缓存

要想提升应用程序服务器的性能,数据缓存可能是性价比最高的办法了。利用 Spring 的缓存抽象注释(@Cacheable@CachePut@CacheEvict@Caching 和@CacheConfig)可以毫不费力地启用数据缓存。在 Spring 配置下,用户还可以把 Ehcache、Memcached 或 Redis 当作基本缓存服务器。

Encache 通常被配置成本地缓存层,具有嵌套结构,在应用的 JVM 上运行。 Memcached 和 Redis 都能作为独立的缓存服务器运行。要想把 Redis 缓存集成到基于 Spring 的应用中,需要使用 Spring Data Redis 的 RedisTemplate 和 RedisCacheManager。

在 Redis 中访问已缓存的对象,耗时通常不到数毫秒,和关系数据库查询相比,这大幅提升了应用程序的性能。

延迟和收益

亚马逊公司在很大程度上依赖缓存服务器来最大程度地减少其零售网站的延迟,该公司甚至曾经发布过一份案例分析,其中记录了延迟和收益之间的关系。

 

本地缓存与远程缓存

在没有网络开销的系统中,本地缓存快于远程缓存。本地缓存的缺点是,同一个对象的多个拷贝在服务器集群中的各个不同节点之中会同步得更快。正因如此,本地缓存仅适用于静态数据,例如可容忍短期滞后和不一致现象的系统级设置。如果为易挥发的业务数据(例如用户数据和交易数据)使用本地缓存,很有可能会以运行应用程序服务器的单个实例而告终。

远程缓存服务器就没有这一局限性。在同一个键的情况下,可保证缓存服务器上的对象只有一个拷贝。只要用户让缓存中的对象及其数据库值彼此保持同步,就无需处理过期数据。

列表 1 给出了一个 Spring 数据缓存的示例。

列表 1:在基于 Spring 的应用中启用缓存

@Cacheable(value="User_CACHE_REPOSITORY", key = "#id")
   public User get(Long id) {  
      return em.find(User.class, id);
}
@Caching(put = {@CachePut(value="USER_CACHE_REPOSITORY", key = "#user.getId()")})  
public User update(User user) {
    em.merge(user);    
    return user;  
}
@Caching(evict = {@CacheEvict(value="USER_CACHE_REPOSITORY", key = "#user.getId()")})  public void delete(User user) {
    em.remove(user);
}
@Caching(evict = {@CacheEvict(value="USER_CACHE_REPOSITORY", key = "#user.getId()")})  public void evictCache(User user) {
}

这里的读取操作被 Spring 的 @Cacheable 注释围绕,作为 AOP 幕僚而执行。Spring 中的存活时间设置也规定了这些对象可在缓存中停留的时间。调用 get() 方法后,Spring 就会试着先从远程缓存读取和返回对象。如果未找到对象,Spring 会执行方法主体,然后将数据库结果放在远程缓存中,之后再返回结果。

但如果另一个过程(例如另一个服务器节点)甚至同一个 JVM 中的另一个线程在数据库中更新了同一个对象,又会怎样呢?如果只运用 @Cacheable 注释,你可能会从远程缓存服务器收到过期拷贝。

为了防止发生这种情况,可以给所有数据库更新操作添加一个 @CachePut 注释。每次调用这些方法时,返回值就会替换掉远程缓存中原先的对象。在数据库读取和写入上都更新缓存,可以让缓存服务器和后台数据之间的记录保持同步。

 

容错

听起来简直完美,对吧?事实当然不是这样。利用列表 1 中的配置,负载较低时可能不会遇到任何问题,但随着服务器集群上的负载逐渐增加,远程缓存上就会出现过期数据。要做好准备应对服务器节点争用甚至更糟的情况。即使成功写入数据库,最后也可能会因为网络故障而使得缓存服务器 PUT 以失败告终。另外,NoSQL 通常不支持在关系数据库中存在完整事务语义,因为这会导致部分提交。为了让代码容错,可以考虑给数据模型增加版本号,实现乐观锁。

在收到 OptimisticLockingFailureException 或 CurrentModificationException(具体取决于持久性解决方案)时,可以调用带有 @CacheEvict 注释的方法,从缓存中清除过期拷贝,然后重试同一个操作:

列表 2:解决缓存中的过期对象

try{
    User user = userDao.get(id);    // user fetched in cache server
    userDao.update(user, oldname, newname);      
}catch(ConcurrentModificationException ex) {   // cached user object may be stale
    userDao.evictCache(user);
    user =  userDao.get(id);     // refresh user object
    userDao.update(user, oldname, newname);    // retry the same operation. Note it may still throw legitimate ConcurrentModificationException.}

结合 Elasticache 使用 Redis

Amazon Elasticache 是一款内存缓存服务,可结合 Memcached 或 Redis 作为缓存服务器使用。虽然 Elasticache 不在本文介绍范围内,但笔者还是想给各位开发人员介绍一个结合 Redis 使用 Elasticache 的技巧。对于大多数 Redis 参数,使用其默认值并无大碍,但 tcp-keepalive 和 timeout 的默认 Redis 设置并不会移除已无效的客户连接,最后还会耗尽缓存服务器上的套接口。结合 Elasticache 使用 Redis 时,务必每次都明确设置这两个值。

在本文的第二部分,将介绍 Redis 的6大用例,敬请期待。

本文系 OneAPM 工程师编译整理。OneAPM 能为您提供端到端的 Java 应用性能解决方案,我们支持所有常见的 Java 框架及应用服务器,助您快速发现系统瓶颈,定位异常根本原因。分钟级部署,即刻体验,Java 监控从来没有如此简单。想阅读更多技术文章,请访问 OneAPM 官方技术博客

本文转自 OneAPM 官方博客

原文地址:http://www.javaworld.com/article/3062899/big-data/lightning-fast-nosql-with-spring-data-redis.html?page=1

 

 
分享到:
评论

相关推荐

    spring data redis api jar

    Spring Data项目旨在简化对各种数据存储技术的访问,包括关系数据库、NoSQL数据库、图数据库等,而Spring Data Redis API则专注于提供与Redis的无缝连接。 Spring Data Redis API的核心特性包括: 1. **连接池支持...

    spring data redis 小例子

    首先,Spring Data Redis是Spring Data项目的一部分,该项目致力于简化各种数据存储的访问,包括关系型数据库、NoSQL存储以及缓存系统如Redis。通过Spring Data Redis,你可以使用Java或Groovy API来方便地执行Redis...

    spring data redis 官方文档

    1. **连接 Redis**:Spring Data Redis 提供了多种方式来配置 Redis 连接,如 Jedis、JRedis(已废弃)、SRP(已废弃)和 Lettuce。 - **Jedis Connector**:使用广泛且稳定的 Java 客户端 Jedis 进行连接配置。 -...

    Spring Data Redis中文参考文档

    1. **高级抽象层**:Spring Data Redis提供了一套高级抽象接口,使得开发人员能够更方便地与Redis进行交互,而无需深入理解底层协议细节。 2. **集成Spring生态**:该模块与Spring框架紧密结合,可以无缝集成到基于...

    Spring-data-redis使用指南

    - **了解 NoSQL 和键值存储**: Redis 是一种键值存储系统,理解其基本原理对于有效使用 Spring Data Redis 至关重要。 - **尝试示例代码**: 通过官方文档提供的示例代码来快速上手。 #### 六、获取帮助 - **社区...

    spring-data + jedis + redis代码

    1. 添加Jedis和Spring Data Redis依赖到项目构建文件(如pom.xml或build.gradle)。 2. 配置Redis连接信息,如主机名、端口、密码等,在Spring的配置文件(如application.yml或application.properties)中。 3. 创建...

    spring-data-redis-1.0.4.RELEASE-dist.zip

    Spring Data提供了一种统一的编程模型,适用于多种数据存储系统,包括关系数据库、NoSQL数据库和键值存储,如Redis。 2. **Redis介绍** Redis是一个高性能的键值存储系统,特别适合于处理大量实时数据。它支持多种...

    spring-data-redis-tools-master.zip

    1. **集成Redis**:Spring Data Redis提供了对Redis的无缝集成,通过配置即可轻松连接到Redis服务器,无需手动编写低级的Redis命令。它通过`RedisTemplate`和`StringRedisTemplate`两个核心类提供了一套完整的数据...

    spring--redis所需要的所有jar

    Spring提供了对多种数据源的支持,包括关系型数据库、NoSQL数据库以及缓存系统如Redis。本篇文章将详细阐述Spring与Redis集成的相关知识点,以及如何利用提供的jar包进行配置与使用。 首先,Redis是一个开源的、...

    spring与Redis的入门Demo

    1. **添加依赖**:在你的项目中,你需要引入 Spring Data Redis 和 Redis 客户端的依赖。在 Maven 项目中,可以在 `pom.xml` 文件中添加如下依赖: ```xml <groupId>org.springframework.boot <artifactId>...

    springboot整合Redis

    Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。 ...

    SpringDataRedisDemo

    Redis是一个高性能的键值对数据库,常用于缓存和消息代理,而SpringDataRedis是Spring Framework的一个模块,它提供了与Redis交互的高级抽象。 在**单机Redis-Demo**中,项目会展示如何配置Spring Data Redis来连接...

    尚硅谷SpringData视频观看下载链接

    1. **SpringData概述** SpringData是Spring生态体系的一部分,旨在通过统一的API简化数据访问。它支持多种数据存储技术,如关系型数据库(JPA、Hibernate)、NoSQL数据库(MongoDB、Couchbase)和搜索引擎(Elastic...

    Spring Redis操作手册

    - **环境配置:** 在正式学习Spring Data Redis前,建议先完成环境配置,确保开发环境支持Redis。 - **资源链接:** - **Redis入门教程:** [Redis入门教程]...

    Redis快速入门ppt(1)

    SpringDataRedis 是一个基于 Spring 框架的 Redis 客户端,提供了对 Redis 的高级操作。 学习目标 本课程的学习目标是: 1. 了解 NoSQL 与关系型数据库的区别 2. 熟悉 Redis 的常用五种数据结构 3. 熟悉 Redis 的...

    Spring Data:Spring Data Modern Data Access for Enterprise Java

    1. The Spring Data Project 2. Repositories: Convenient Data Access Layers 3. Type-Safe Querying Using Querydsl . . Part II. Relational Databases 4. JPA Repositories 5. Type-Safe JDBC Programming with ...

    SpringData.pdf

    对于NoSQL数据库,SpringData支持MongoDB(文档数据库)、Neo4j(图形数据库)、Redis(键/值存储)和Hbase(列族数据库)。对于关系型数据库,SpringData主要支持JDBC和JPA技术。 SpringDataJPA是SpringData项目中...

    redis nosql java

    3. **Spring Data Redis**:作为Spring框架的一部分,Spring Data Redis提供了一套完整的解决方案来简化Redis与Java应用的集成。 - **RedisTemplate**:用于执行CRUD操作,支持各种数据结构的操作。 - **Redis配置...

    Spring Data实战

    Spring Data主要分为多个模块,如JPA、MongoDB、Neo4j、Redis等,分别对应不同的数据存储技术。每个模块都提供了与特定存储系统交互的API和工具。 3. **Repository抽象** Spring Data的核心是Repository抽象,它...

Global site tag (gtag.js) - Google Analytics