领先一步
VMware 提供培训和认证,助您快速提升技能。
了解更多NoSQL 解决方案流行的一个驱动因素是其性能(尤其是在高负载下)。由于其数据模型,键值存储处于领先地位,它提供了一种轻量级但灵活的数据处理方式。在本篇文章中,我将快速展示如何使用 Spring(Spring Redis)和 Spring Data 的一个示例(RetwisJ)来使用键值存储(Redis),并将应用程序部署到云(通过 Cloud Foundry)与世界分享。我甚至更进一步,使用 Windows 作为部署平台。
RetwisJ 源代码(包括本博客中的代码)可以在 Spring Data Key Value 的示例项目中下载。此外,文档可在此处获得。
RetwisJ 可以看作是 Redis 的Retwis示例的 Java 版本:一个简单的 Twitter 克隆,它演示了如何用 Redis 灵活的数据模型(例如集合交集)替换传统关系数据库中代价高昂的连接。
从表式思维迁移到键值关联可能看起来很困难,但事实并非如此:与其在一个键下存储多个值,不如在“相似的键”下存储每个值;事实上,关系本身也可以这样存储。如文档中所述,与其为用户创建一个表(包含用户名、密码等列),不如通过 Redis 哈希(或映射)存储项目,并且与其创建索引来存储条目之间的关系,不如为其添加单独的反向或查找键。因此,以下表结构(用户)可以部署为以下键值对:
键 用户名 密码
1 springrod interface21
2 costinl this 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 的文档。
Java 用户连接到 Redis 时遇到的一个常见问题是使用哪个客户端(或驱动程序)。Spring Redis 以一致的方式支持三个不同的库(Jedis、JRedis 和RJC),因此可以在它们之间切换而无需重写任何代码。让我们选择 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类和两个领域对象Post和User组成。为了遵循 Retwis 示例,即使安全性也将通过 Redis 来处理,而不是容器HttpSession- 这不仅演示了键值存储的另一个用例,而且还提高了可伸缩性,因为 Redis(以及用户数据)是开箱即用的分布式。
要构建它,只需在根文件夹中键入
./gradlew build
要运行它,请将生成的 war 文件(build/libs/retwisj.war)部署到您选择的 Web 容器中。
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/访问。
尝试一下,让我们知道您的想法和需求!