第 2 部分: 将 Riak 集成为 Web 应用程序的重负荷缓存服务器  http://www.ibm.com/developerworks/cn/opensource/os-riak2/

简介

某些类型的数据表现出使自己适合于被缓存的访问模式。例如,在线投注站点具有一个有趣的负载特征:用户常常请求提供赔率和投注单,而这些信息相对来说很少被更新。

这些情况需要具有以下特征的高度可扩展的系统,以应对高负荷的要求:

  • 该系统充当一个可靠的缓存,以减少对应用服务器和数据库的需求
  • 缓存项目是可搜索的,所以您可以更新它们或使它们失效
  • 任何解决方案都能被轻松地集成到现有站点

Riak 对于这样的解决方案是一个不错的选择。

Riak 对于实现这样一个缓存解决方案并非惟一的候选者;有许多不同的缓存可用。其中较为流行的一种是 memcached;然而,与 Riak 不同,memcached 不提供任何类型的数据复制,这意味着,如果保存特定项目的服务器停机,该项目会变得不可用。另一种流行的键/值存储是 Redis,它也可作为缓存使用,通过主从配置支持复制;Riak 没有一个主人(节点)的概念,因此,这使系统对故障更有弹性。

网站集成

任何解决方案都需要很容易地被集成到现有网站。能够做到这一点很重要,因为并不一定有可能(或者甚至有需要)将您现有的全部数据迁移到 Riak。如前所述,某些类型的数据适合缓存,在一个键/值存储的情况下,如果您通过一个主键访问数据则更是如此。这是一种更适合迁移到 Riak 的数据。

正如在本系列的有关 Riak 的 Riak 简介,第 1 部分:与语言无关的 HTTP API 所述,PHP、Ruby 和 Java™ 等语言中提供了大量客户端库;这些库提供一个 API,使集成 Riak 非常简单。在本例中,我演示了 PHP 库的使用,以展示如何将 Riak 与现有网站集成。

图 1 显示了本例需要考虑的设置。我忽略了负载均衡、防火墙等细节。在本例中,服务器本身只是安装了一个 LAMP 堆栈的简单的前端箱。

我将假设,Riak 仅在内部使用(不能从外面访问它),且在一个非敌对的环境中运行,所以不存在身份验证等与安全相关的问题。该假设并不是像它看起来那么差劲,因为不管怎样 Riak 并没有任何内置的授权;您真的应该将身份验证等安全措施委托给应用程序。

图 1. 一个简单的网站集成

下面是一个基本示例,演示您可以如何将 Riak 集成到您的现有网站。您将创建一个简单的表单,在提交表单时,根据在表单中输入的值,该表单将使用 PHP 客户端存储 Riak 中的对象。

图 2 显示了一个简单的表单示例,管理员可能会使用它在系统中创建一个投注项。用 HTML 创建该表单,并让它对 清单 1 中的 PHP 脚本执行一个 POST;您可以将本文所附的 源代码 中的类似表单作为一个起点。表单中输入的 “key” 字段将被用作在桶中存储的对象的键。

图 2. 创建投注的示例表单

清单 1 的示例 PHP 代码显示了如何使用 PHP 客户端库来集成 Riak。将 PHP 客户端库路径(在 require_once 中指定)更改为您安装它的位置。在本例中,我只是将它与 PHP 脚本放在同一目录中。默认情况下,所有的客户端库都期待在端口 8098 上提供 Riak。

清单 1. 集成 Riak 的示例 PHP 代码
<?phprequire_once('./riak.php');# Could do check here to see if the current user has the
# appropriate credentials ? delegated to application.$client = new RiakClient('192.168.1.1', 8098);
$bucket = $client->bucket('odds');$bet = $bucket->newObject($_POST['key']);
$data = array('odds' => $_POST['odds'],'description' => $_POST['description']
);
$bet->setData($data);# Save the object to Riak
$bet->store();echo "Thanks!";
?>

将代码保存为一个 PHP 文件(按您喜欢的方式命名),将其和表单上传到您的网站上的某个位置,例如,http://www.yoursite.com/riak-test.php。填写示例表单,并提交它。为了证明它有效,尝试使用您在创建项目时在表单中输入的键直接从 Riak 中检索(参见 清单 2)。

清单 2. 从 Riak 中检索项目
$ curl -i http://localhost:8098/riak/odds/<key>
...
{ "odds":"", "description":"" }

虽然该集成示例使用了 PHP 客户端,但其方法与 Java 或 Ruby on Rails 等其他语言或应用程序框架类似。

回页首

直接向请求提供服务

除了使用客户端库将 Riak 集成到当前设置外,还可以从 Riak 向用户请求直接提供服务,并将它用作一个简单的 HTTP 引擎。为了演示这一点,我将创建一个简单的演示,向您展示如何从 Riak 直接请求页面。

下载本文的 源代码。请确保 Riak 正在运行,然后执行脚本 load.sh。这个脚本会将所有的 HTML 和 JavaScript 文件复制到一个名称为 demo 的桶中。本例使用 JavaScript 客户端。

要查看演示,请在您的浏览器中打开以下 URL:http://localhost:8098/riak/demo/demo.html

如果您在表单中输入了一些值来创建一个投注,并提交了表单,则会将一个 JSON 对象存储在 Riak 中。对象的属性将与表单中的字段对应。您会被重定向到一个显示您刚刚创建的对象值的页面。

清单 3 显示通过您输入的值来创建对象的代码。keyodds 和 description 等值来自在表单中输入的值。

清单 3. JavaScript 客户端库在 Riak 中的示例用法
client.bucket("odds", function(bucket) {var key = $('#key').val();bucket.get_or_new(key, function(status, object) {object.contentType = 'application/json';object.body = { 'odds': $('#odds').val(), 'description': $('#desc').val() };object.store(function(status, object, request) {if (status == 'ok') {window.location = "http://localhost:8098/riak/odds/"+key;} else {alert("Failed to create object.");}}); });
});

如前所述,我假设,Riak 在一个可信的环境中运行。在这种情况下,Riak 中用于存储和检索项目所添加的页面就不会产生安全问题;但是,您并不希望这种功能在没有某种形式的身份验证的前提下就完全暴露在 Internet 中。

虽然这是一个简单的示例,但它使您了解到了 Riak 如何可以直接向页面请求提供服务。例如,您可以使用 JSONP 或跨源资源共享(AJAX 请求被相同的域策略限制在页面所驻留的同一台服务器上)等技术,也可以代理通过服务器向 Riak 发送的请求,从而在您现有的 Web 页面中直接包括存储在 Riak 中的数据,以获取所需的数据。

使用 Riak 作为缓存

缓存用于提供数据的快速访问。如果缓存中包含了请求的数据(缓存命中),应用程序可以通过从缓存中读取值来快速向请求提供服务,这比从数据库中检索值更快。如果缓存中没有数据(缓存未命中),那么应用程序通常必须在数据库中检索数据。一般情况下,您可以从缓存中服务的请求越多,系统将会越快。Riak 具有多项特性,这使其成为缓存解决方案实现的一个不错的选择。

其中一个这样的 Riak 特性是其可插拔的 (pluggable) 存储后端;存储后端决定如何存储数据。有若干个可用的存储后端,但我不打算在这里全部一一介绍(有关更多信息,请参阅 参考资料)。默认存储后端是 Bitcask,这是一个 Erlang 应用程序,提供一个 API,用于存储和检索受散列表支持的数据,该散列表提供了数据的快速访问;数据是永久性的。

有一个后端也许与本文关系更紧密:Memory 后端。Memory 后端使用一个内存表来存储其所有的数据(它在内部使用 Erlang 的 ets 表),并且,在启用时,使 Riak 的行为像一个设定了有效期的 LRU 缓存。比起必须在磁盘上检索数据,使用内存存储的优势在于它明显快得多。当数据被存储在内存中(它不是永久的)且一个节点出现故障时,在该节点中存储的数据将丢失。若您将它用作缓存,这就不是一个问题了(应用程序总是可以从数据库检索数据),就像您将 Riak 用作主数据存储一样。Riak 在集群中跨多个节点复制数据,因此它仍然是可用的。

Riak 自带 Memory 后端。为了使用 Memory 后端,请打开集群中每个节点的 app.config,定位属性 storage_backend,并将其从riak_kv_bitcask_backend 更改为 riak_kv_memory_backend。现在将 清单 4 中的代码添加到文件的末尾。

清单 4. 使用 Memory 后端
{memory_backend, [{max_memory, 4096},    %% 4GB of memory{ttl, 86400}        %% Time in seconds
]}

将值更改为适合于您的设置的值。重新启动集群中的节点。

在 Riak 集群内也可以运行多个存储后端。这非常有用,因为这意味着可以针对不同的桶使用不同的后端。例如,您可以配置一个桶(让我们称之为 cache)来使用 Memory 后端,但对于其他桶(那些应当保存数据的桶),则使用 Bitcask。

既然您已经让 Riak 设置的行为像缓存一样,那么您需要一些方法来访问集群中的数据,以便更新它,或出于某种原因使它失效(在它的有效期结束前)。

查找什么内容吗?

正如您已经看到的,当使用 HTTP 界面检索在 Riak 中存储的数据时,您要构造一个 URL,其中包括桶的名称以及您要检索的对象的键,然后在该 URL 上执行一个 HTTP GET。当您知道键是什么时,这就完全足够了!但是,有时您并不知道要检索的对象的键,或者您要检索满足一定条件的一组对象。那么,您需要一种方法来搜索在集群中保存的对象。

您已经看到如何通过存储在集群中的文档运行一个 Map/Reduce 作业来查询数据。一般来说,执行查询的时间与集群中的文档数量成正比;文档越多,查询这些文档所需要的时间越长。对于时间不敏感的查询,这不是一个问题。我这样说的意思是,用户并不指望立即得到答复的查询。对于像搜索这样的操作,每次都(动态)搜索所有文档是不可行的;获得结果的时间可能是几分钟,也可能是几小时!

幸运的是,Riak 对该问题已经有一个解决方案:Riak Search。Riak Search 提供搜索存储在整个集群中的文档时所需要的功能。搜索这个主题对于本文来说过于庞大,无法深入讨论,但从高层次来说,它的工作方式是这样的:文档被标记化(Riak Search 使用标准的 Lucene 分析器),并被添加到一个反向索引。然后,根据用户输入的搜索项查询该索引。当新文件被添加时,它们也被索引并添加到索引中。

Riak Search 默认被禁用。在您可以使用它之前,您需要先启用它。在集群中的每个节点上,打开 rel/riakN/etc/app.config,定位属性riak_search 并将它设置为 true。您需要重新启动集群中的节点。

Riak 通过使用提交前 (pre-commit) 和提交后 (post-commit) 挂钩,允许您指定文档被添加到桶之前和之后要运行的函数的名称。例如,在将文档添加到桶之前,您可能要检查文档是否有特定的必需字段。要搜索一个文档,需要先对其进行索引。要做到这一点,需在存储文档的桶上安装一个 pre-commit 挂钩。要做到这一点,请运行以下命令:$ rel/riak/bin/search-cmd install <bucket name>

这将在桶上安装一个提交前挂钩 riak_search_kv_hook。现在,每当文档被添加到该桶,它就会被分析,并被添加到索引。空白分析器是默认的分析器;它基于空白将字符处理成标记,然后标记被索引。有一些不同的分析器可供使用,您也可以定义自己的分析器。

在许多情况下,Riak Search 知道如何索引您的数据。例如,开箱即用的,如果一个 JSON 对象被添加到某个桶,每个属性的值将被索引,并且可以在查询字符串中使用属性名称来查询。搜索示例请参见 清单 5。对于更复杂的结构,您可以定义自己的模式,告诉 Riak Search 如何索引数据。

当您已索引一些文档后,您需要能够对它们发出查询。一种方法是从 Erlang shell 运行查询。例如,在 清单 5 中的查询搜索与赛马有关的所有投注的赔率桶;您通过查询存储项的 description 属性完成该搜索。

清单 5. 搜索与赛马有关的投注的赔率桶
$ rel/riak/bin/riak attachsearch:search(<<"odds">>, <<"description:horse">>).

此外,Riak Search 还为文档搜索提供了一个 Solr 兼容的 HTTP API。Apache Solr 是一个流行的企业搜索服务器,带有一个类似于 REST 的 API。通过使 API 与 Solr 兼容,应该可以断开 Solr(如果您使用它),并改为使用 Riak Search 支持搜索。例如,要使用 Solr 界面搜索特定活动的赔率,您可以这样做:$ curl "http:localhost:8098/solr/odds/select?start=0&q=description:horse"

利用搜索设置,您现在即使不知道正在查找的项目的主键,也可以在数据存储中定位这些项目。

结束语

Riak 的扩展能力和可靠地复制数据的能力(加上搜索等其他特性)使其成为实现重负载站点的缓存解决方案的理想选择。您可以很容易地将它集成到现有站点。利用其直接为请求提供服务的能力,您可以使用 Riak 减少和消除应用程序和数据库服务器上的负载。

参考资料

学习

  • Riak 简介,第 1 部分:与语言无关的 HTTP API(Simon Buckle,developerWorks,2012 年 3 月):阅读这个对 Riak 的简介,它涵盖了使用 Riak 的 HTTP API 存储和检索 Riak 中的项目的基础知识。
  • 阅读 Riak Search 维基页面,了解有关其工作方式的更多信息。
  • 查看 Riak 提供的 存储后端,以及它们彼此有何差异。
  • 获取用于集成 Riak 的 可用客户端库的列表。
  • 查看 Basic Cluster Setup and Building a Development Environment,了解有关设置一个三节点集群的更多详细信息。
  • 阅读 Google 的 MapReduce: Simplified Data Processing on Large Clusters。
  • 阅读 Erlang 编程简介,第 1 部分(Martin Brown,developerWorks,2011 年 5 月)并了解 Erlang 的概况,以及它的函数编程风格与其他编程范式(比如命令式、过程式和面向对象编程)的比较。
  • 阅读 Amazon's Dynamo paper,Riak 以此为依据。强烈推荐!
  • 阅读文章 How To Analyze Apache Logs,了解如何使用 Riak 处理服务器日志。
  • 了解 vector clocks 的解释,以及它们比想象中更容易理解的原因。
  • 在 Riak 维基上查找 vector clocks 的详细解释以及有关 link walking 的更多详细信息。
  • 如果您需要一些文本资源进行实验,Project Gutenberg 站点 是一个很好的资源。
  • developerWorks 中国网站 Web 开发专区 专门提供介绍各种基于 Web 的解决方案的文章。
  • 观看 developerWorks 演示中心,那里提供了包括面向初学者的产品安装和配置演示,以及为经验丰富的开发人员提供的高级功能。
  • 随时关注 developerWorks 技术活动和网络广播。
  • 访问 developerWorks Open source 专区获得丰富的 how-to 信息、工具和项目更新以及最受欢迎的文章和教程,帮助您用开放源码技术进行开发,并将它们与 IBM 产品结合使用。

获得产品和技术

  • 以最适合您的方式 IBM 产品评估试用版软件:下载产品试用版、在线试用产品、在云环境中使用产品,或在 IBM SOA 人员沙箱 中花一些时间了解如何高效实现面向服务的架构。

讨论

  • 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
  • 加入 IBM 软件下载与技术交流群组,参与在线交流。

Riak 简介(2)相关推荐

  1. Riak 简介,第 1 部分: 与语言无关的 HTTP API

    转载:http://www.ibm.com/developerworks/cn/opensource/os-riak1/index.html 简介 典型的现代关系数据库在某些类型的应用程序中表现平平, ...

  2. riak文件服务器,riak简介(一)

    本人机子为ubuntu.所以安装比较简单 sudo apt-get install openssl sudo apt-get install erlang下载deb包安装 wget -c http:/ ...

  3. Riak - 背景篇(3)

    分布式高可用键值对数据库Riak - 背景篇(3) Dynamo对于数据版本的处理 数据版本问题不止存在于分布式系统,这里针对分布式数据库系统简单讨论下.先看一个简单的例子,用户x对key1做了一次写 ...

  4. Riak - 背景篇(1)

    分布式高可用键值对数据库Riak - 背景篇(1) Riak简介 典型的现代关系数据库在某些类型的应用程序中表现平平,难以满足如今的互联网应用程序的性能和可扩展性要求.因此,需要采用不同的方法.在过去 ...

  5. mysql 从零开始_MySQL从零开始:01 数据库简介

    1.什么是数据库 从字面意思理解,首先数据库是一个存放东西的库,里面存的东西是数据.以下解释来自百度百科: 数据库(Database)是按照数据结构来组织.存储和管理数据的建立在计算机存储设备上的仓库 ...

  6. 领域应用 | 图数据库及其在恒昌的应用简介

    首发于知乎专栏知识图谱和智能问答,作者为量子胖比特. 背景 历史上,多数企业级应用都运行在一个关系型数据库上(RDBMS),近年来,随着数据存储技术的飞速发展,关系型数据库在灵活性和可伸缩性方面不再处 ...

  7. NoSQL和Redis简介及Redis在Windows下的安装和使用教程

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/103.html?1455869099 NoSQL简介 介绍redis前,我 ...

  8. Redis学习 - NoSQL简介、redis安装、redis基础知识、数据类型、持久化、订阅发布、主从复制、哨兵模式、缓存击穿和雪崩

    学习视频地址:https://www.bilibili.com/video/BV1S54y1R7SB 完结撒花,感谢狂神 文章目录 1. NoSQL 1.1 单机Mysql的演进 1.2 当今企业架构 ...

  9. 对Riak Core的探索 (1) Hello

    haogongju.人人IT网.59n南龙.360doc不要抄我的烂博客了,私人备忘用. [size=x-large]基于Riak Core的开发指南[/size] [size=large]1. he ...

最新文章

  1. Java创建初始化List集合的几种方式
  2. tensorflow 教程 梯度下降法实现线性回归问题
  3. mfc cef cefsettings 单进程 退出_PyTorch 64.进程池Pool的imap方法
  4. 字节2020算法岗校招一面
  5. dedecms /plus/feedback.php SQL Injection Vul
  6. java图形界面_Java自学-图形界面 面板
  7. 人生哲理---你值得借鉴
  8. linux内核head.S文件分析
  9. Benchmark简介
  10. html动态创建table不成功的一个问题
  11. java异常处理中的返回值
  12. 计算机 上的图片怎样加密码,电脑照片文件怎么加密?电脑文件加密软件介绍...
  13. 微信付款到个人银行卡php,微信企业付款到银行卡(下)
  14. Java基础视频教程(2020年最新)
  15. mysql 出现2003- cant connect to MYSQL server on localhost 的解决办法
  16. TextGrabber重大更新,识别文字并实时离线翻译,支持中文
  17. LInux sed命令详解
  18. 【python】根据文件(图片)名字,删除符合条件的文件(图片)
  19. C语言如何动态申请空间(一维和二维)
  20. 学物理可以让我们永远年轻吗?

热门文章

  1. 数字扫描变换技术 matlab代码,基于Matlab的数字扫描变换器设计
  2. Java代码实现解压文件包和压缩文件的工具类
  3. 为什么只有跳槽才能涨工资
  4. 要怎么才能有效降低论文的查重率呢?
  5. js单线程,事件循环,微任务宏任务
  6. 2019全国计算机大赛二等奖,喜讯!这次是2019年TI杯全国大学生电子设计竞赛全国二等奖...
  7. H.264几大开源编码器简介
  8. H.264编码器在需要时强制插入关键帧
  9. 个人怎么做微信小程序?个人开发者也可以这样开发属于自己的小程序
  10. amazon linux虚拟主机,如何在Amazon AWS上设置Linux服务器