Redis、Spring Data 和 Cloud Foundry 快速入门

工程 | Costin Leau | 2011年4月27日 | ...

NoSQL 解决方案流行的一个驱动因素是其性能(尤其是在高负载下)。由于其数据模型,键值存储处于领先地位,它提供了一种轻量级但灵活的数据处理方式。在本篇文章中,我将快速展示如何使用 Spring(Spring Redis)和 Spring Data 的一个示例(RetwisJ)来使用键值存储(Redis),并将应用程序部署到(通过 Cloud Foundry)与世界分享。我甚至更进一步,使用 Windows 作为部署平台。

Redis

Redis 是键值存储中一个流行的选择,它是一个开源的、极速的数据库,用 ANSI C 编写,服务器端大小约 200 KB(是的,字节),整个包(包括命令行客户端和一些管理实用程序)约 400 KB,几乎可以在所有主要平台上使用,这也使其成为示例的理想选择。请注意,除非要本地运行示例,否则不需要 Redis 实例。如果是这样,对于 Windows 用户(例如作者),本人使用(并推荐)这个预打包版本,提供 32 位和 64 位版本。

Spring 和 NoSQL

如果您在 Java 环境中使用 NoSQL,请查看Spring Data:它本身并不是一个项目,而是一个项目的集合,它包含各种新的数据访问技术,例如非关系型数据库(如 Redis 或 MongoDB)、MapReduce 框架(例如 Hadoop)和面向 Java 应用的云端数据服务。Spring Data 推广了 *经典* 的 Spring 价值观,通过消除 API 冗余、样板代码和资源管理来提高开发人员的生产力,并提供一致的编程模型。它构建在现有的 Spring 功能和项目(例如控制反转、生命周期管理、类型转换、可移植数据访问异常、缓存等)之上,因此可以轻松地将其添加到应用程序中。当然,与其他 Spring 项目一样,它是开源的,并根据 Apache 许可证提供。

Spring Data Redis

对于 Redis,Spring Data 通过 Spring Data Redis 或简称为Spring Redis项目提供专门的支持。它提供了低级和高级功能,从可移植的 Redis 客户端抽象(允许轻松更改不同的 Redis 客户端,例如 Jedis、JRedis 或 RJC,只需一行配置)到 Redis 支持的原子集合或计数器或发布-订阅支持。该项目的参考文档详细介绍了这些主题。

RetwisJ,又一个 Twitter 克隆

RetwisJ 源代码(包括本博客中的代码)可以在 Spring Data Key Value 的示例项目中下载。此外,文档可在此处获得。

RetwisJ 可以看作是 Redis 的Retwis示例的 Java 版本:一个简单的 Twitter 克隆,它演示了如何用 Redis 灵活的数据模型(例如集合交集)替换传统关系数据库中代价高昂的连接。

从表式思维迁移到键值关联可能看起来很困难,但事实并非如此:与其在一个键下存储多个值,不如在“相似的键”下存储每个值;事实上,关系本身也可以这样存储。如文档中所述,与其为用户创建一个表(包含用户名、密码等列),不如通过 Redis 哈希(或映射)存储项目,并且与其创建索引来存储条目之间的关系,不如为其添加单独的反向或查找键。因此,以下表结构(用户)可以部署为以下键值对:

用户名密码
1springrodinterface21
2costinlthis is fun
  变成  
类型
uid:1哈希{name: springrod, pass: interface21}
uid:2哈希{name: costinl, pass: secret}

同样,关注者和被关注者(或目标)之间的关联表可以通过 Redis 集合进行映射。因此,与其执行表连接,不如简单地进行集合交集。Redis 丰富的数据模型(集合、Z集合(或有序集合)、列表和哈希)通过 Spring Redis 很好地映射到 Java 集合,Spring Redis 在 Redis 之上提供了相应的java.util实现。这意味着可以使用众所周知的接口来遍历、查找或修改列表和集合,而无需手动发出任何 Redis 命令。

举例说明

private RedisSet<String> following(String uid) {
   return new DefaultRedisSet<String>(KeyUtils.following(uid), template);
}
      
public Collection<String> commonFollowers(String uid, String targetUid) {
   Set<String> followers = following(uid).
       intersectAndStore(following(targetUid),
       KeyUtils.commonFollowers(uid, targetUid));
   ...
}

对于通用数据访问,Spring Redis 的核心是RedisTemplate它允许进行从简单的一行富对象的操纵、序列化(无论是字节数组、XML 还是基于 Jackson 的)或消息发布到高级查询功能和数据获取(例如通过 Redis SORT/GET 模式避免臭名昭著的 N+1 问题)的一切操作。

// adding entries into a hash
BoundHashOperations<String, String, String> userOps = template.boundHashOps(KeyUtils.uid(uid));
userOps.put("name", name);
userOps.put("pass", password);
valueOps.set(KeyUtils.user(name), uid);

有关数据模型和示例的更深入解释,请参阅 RetwisJ 的文档

连接到 Redis

Java 用户连接到 Redis 时遇到的一个常见问题是使用哪个客户端(或驱动程序)。Spring Redis 以一致的方式支持三个不同的库(JedisJRedisRJC),因此可以在它们之间切换而无需重写任何代码。让我们选择 Jedis 并查看应用程序配置是什么样的。

<beans>
  <context:property-placeholder location="classpath:redis.properties"/>

  <!-- Redis client -->
  <bean id="connectionFactory" class="org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory"
		p:host-name="${redis.hostname}" p:port="${redis.port}" p:password="${redis.password}"/>

	<bean id="redisTemplate" class="org.springframework.data.keyvalue.redis.core.StringRedisTemplate" 
		p:connection-factory-ref="connectionFactory"/>

	<context:annotation-config />
	<context:component-scan base-package="org.springframework.data.redis.samples"/>

</beans>

非常简单 - 我们声明驱动程序和 Redis 属性(通过属性占位符从redis.properties中在运行时替换),我们启用注释配置并扫描类路径中的 bean。

从部署角度来看,RetwisJ只是一个 Web 应用,一个 WAR 文件,可以部署到任何(Servlet 2.5)Web 容器(例如 Tomcat)。它由一个简单的 Spring@MVC控制器、一个Repository类和两个领域对象PostUser组成。为了遵循 Retwis 示例,即使安全性也将通过 Redis 来处理,而不是容器HttpSession- 这不仅演示了键值存储的另一个用例,而且还提高了可伸缩性,因为 Redis(以及用户数据)是开箱即用的分布式。

要构建它,只需在根文件夹中键入

./gradlew build

要运行它,请将生成的 war 文件(build/libs/retwisj.war)部署到您选择的 Web 容器中。

将 RetwisJ 部署到 Cloud Foundry

Cloud Foundry 就绪的 RetwisJ 示例可在专用示例存储库中找到。

将上面的 WAR 文件部署到 Cloud Foundry 非常简单 - 您只需要一个帐户(您可以在此处免费注册)。完成后,您可以使用它通过 STS 部署您的应用程序(如之前的文章中详细描述的那样),或者使用命令行(vmc),这正是我在本篇文章中将要使用的。

由于我们使用的是 Redis,因此我们需要将本地实例属性替换为适用于 Cloud Foundry 的属性,这些属性作为环境属性公开。如这些文档中所述,通过cloud命名空间提供了专门的 Spring 支持。

我们可以使用它,因此与其从本地文件读取 Redis 属性,不如从环境中读取它们。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:p="http://www.springframework.org/schema/p"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:cloud="http://schema.cloudfoundry.org/spring"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://schema.cloudfoundry.org/spring http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd">

  	<cloud:service-properties id="cfoundryEnv" />
  	<context:property-placeholder properties-ref="cfoundryEnv"/>
	  
    <bean id="connectionFactory" class="org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory"
      p:host-name="${redis.hostname}" p:port="${redis.port}" p:password="${redis.password}"/>

属性名称不必更改 - 我们可以命名(在本例中为 *redis*)绑定到应用程序的 Redis 实例,并使用它来最大程度地减少本地环境和云之间的更改。

请注意,这只是许多选项中的一种:您可以使用 Spring 3.1 的配置文件来自动进行切换,使用云命名空间来自动为您创建RedisConnectionFactory或将其自动连接到您的应用程序。有关可用各种功能的更多信息,请参阅此部分

现在让我们将我们的 Twitter 克隆部署到云中!

对于像我这样的命令行爱好者,Cloud Foundry 提供了vmc实用程序,它允许您与 Cloud Foundry 实例进行交互。它是用 Ruby 编写的,因此需要安装 Ruby 和 Ruby Gem - 请参阅下载页面以获取适合您操作系统的软件包。对于 Windows,出色的RubyInstaller(安装程序或 zip 格式)通过提供原生集成(如果您不想使用 Cygwin 等,则无需使用)很好地解决了这个问题。如果gem命令不可用,请从官方网站下载它,解压缩它,就可以了。

有关可用命令的更多信息,请参阅入门指南

q:\>gem install vmc
Successfully installed vmc-0.3.10
1 gem installed
Installing ri documentation for vmc-0.3.10...
Installing RDoc documentation for vmc-0.3.10...

登录我们的帐户

Q:\>vmc target api.cloudfoundry.com
Succesfully targeted to [http://api.cloudfoundry.com]

Q:\>vmc login
Email: <signup email>
Password: **************
Successfully logged into [http://api.cloudfoundry.com]

最后一步是简单地上传我们的 WAR 文件


Q:\>dir /B
retwisj.war

Q:\>vmc push
Would you like to deploy from the current directory? [Yn]: y
Application Name: my-retwisj
Application Deployed URL: 'my-retwisj.cloudfoundry.com'?
Detected a Java SpringSource Spring Application, is this correct? [Yn]: y
Memory Reservation [Default:512M](64M, 128M, 256M, 512M or 1G)
Creating Application: OK
Would you like to bind any services to 'my-retwisj'? [yN]: y
The following system services are available::
1. mongodb
2. mysql
3. rabbitmq
4. redis
Please select one you wish to provision: 4
Specify the name of the service [redis-866fb]: redis
Creating Service: OK
Binding Service: OK
Uploading Application:
  Checking for available resources: OK
  Processing resources: OK
  Packing application: OK
  Uploading (32K): OK
Push Status: OK

Staging Application: OK

Starting Application: OK

Q:\>vmc apps

+-------------+----+---------+------------------------------+-------------+
| Application | #  | Health  | URLS                         | Services    |
+-------------+----+---------+------------------------------+-------------+
| my-retwisj  | 1  | RUNNING | my-retwisj.cloudfoundry.com  | redis       |
+-------------+----+---------+------------------------------+-------------+

即使在连接速度慢的情况下,上述过程也不应该超过 1 分钟(本博客的文章提供了在push操作期间发生的情况的见解)。您可能已经注意到,只上传了 32K;这并非错误,vmc足够聪明,可以确定它已经知道的(例如已经部署的)文件和实际更改的文件。

就是这样!- 只需将您的浏览器指向上面的 URL 并享受您的 RetwisJ 示例。“官方”实时实例可在http://retwisj.cloudfoundry.com/访问。

总结

本篇文章涵盖了很多内容:Redis、Spring Data 和 Cloud Foundry 部署。我希望这能展示开始使用该组合是多么容易,以及该组合在本地环境或云环境中的强大功能。而这仅仅是个开始!预计 Spring Redis(即将发布 RC 版本)以及 Cloud Foundry(无论是更多服务还是更好的工具)都将添加更多功能。

尝试一下,让我们知道您的想法和需求!

获取 Spring 时事通讯

通过 Spring 时事通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您快速提升技能。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅,提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看全部