转载请注明出处:http://blog.csdn.net/lonelytrooper/article/details/9982967

Redis服务器

Redis是一套高级的用于持久化的内存KeyValue存储系统(见http://redis.io)。使用它来存储下述信息:

﹒产品信息,用于服务网站。

﹒用户导航队列,用于供给Storm Topology。

﹒Storm Topology中间数据,用于Topology从失败中恢复。

﹒Storm Topology结果,用于存储预期的结果。

生产信息

Redis服务器存储产品,它使用产品ID作为键,包含所有产品信息的JSON对象作为值。

用户导航队列

用户导航队列被存储在一个命名为导航的Redis列表中并且被组织成一个先进先出(FIFO)的队列。每次用户访问一个产品页,服务器添加一个项到列表左端,以此来表明哪个用户访问了哪个商品。Storm集群不时地从列表的右端删除元素来处理信息。

中间数据

集群需要分别存储每个用户的历史记录。为达到这个目的,它在Redis服务器中保存了一个集合,该集合存储了每个用户浏览的所有产品及它们的分类。

结果

集群产生用户访问特定产品的有用数据并且将它们存储在命名为”procnt”的Redis Hash中:后边紧跟着产品ID。

测试Topology

为了测试topology,使用提供的LocalCluster和一个本地的Redis服务器(见图6-7)。你将在初始化时填充产品数据库并且在Redis服务器上模拟浏览日志的插入。我们的断言将通过读取topology输出到Redis服务器来执行。测试用Java和Groovy编写。

图6-7. 测试架构

测试初始化

初始化由三步组成:

启动LocalCluster并提交Topology. 初始化在AbstractAnalyticsTest中被执行,该类被所有的测试继承。一个叫做topologyStarted的静态标志被用来避免当多个AbstractAnalyticsTest子类初始化时AbstractAnalyticsTest本身被初始化不止一次的情况。

注意那里sleep的目的是允许LocalCluster在尝试从中恢复结果之前正确的启动。

public abstract class AbstractAnalyticsTest extendsAssert {

def jedis

static topologyStarted= false

static sync=new Object()

private voidreconnect(){

jedis =new Jedis(TopologyStarter.REDIS_HOST,TopologyStarter.REDIS_PORT)

}

@Before

public voidstartTopology(){

synchronized(sync){

reconnect()

if(!topologyStarted){

jedis.flushAll()

populateProducts()

TopologyStarter.testing= true

TopologyStarter.main(null)

topologyStarted =true

sleep 1000

}

}

}

...

public voidpopulateProducts(){

def testProducts = [

[id:0, title:"Dvdplayer with surround sound system",

category:"Players",price: 100],

[id:1, title:"FullHD Bluray and DVD player",

category:"Players",price:130],

[id:2, title:"Mediaplayer with USB 2.0 input",

category:"Players",price:70],

...

[id:21, title:"TVWall mount bracket 50-55 Inches",

category:"Mounts",price:80]

]

testProducts.each(){product ->

def val =

"{ \"title\":\"${product.title}\" , \"category\":\"${product.category}\","+

" \"price\": ${product.price},\"id\": ${product.id} }"

println val

jedis.set(product.id.toString(),val.toString())

}

}

...

}

在AbstractAnalyticsTest类中实现一个叫做navigate的方法。为了使不同的测试有一种来模拟用户导航页面行为的方式,该步在Redis服务器导航队列中插入导航项。

public abstract class AbstractAnalyticsTest extendsAssert {

...

public voidnavigate(user,product) {

String nav =

"{\"user\": \"${user}\",\"product\": \"${product}\", \"type\":\"PRODUCT

\"}".toString()

println "Pushingnavigation: ${nav}"

jedis.lpush('navigation',nav)

}

...

}

在AbstractAnalyticsTest中提供一个叫做getProductCategory的方法来从Redis服务器中读取特定的关系。不同的测试也需要对统计的结果进行断言来确保topology按预期的运行。

public abstract class AbstractAnalyticsTest extendsAssert {

...

public intgetProductCategoryStats(Stringproduct,Stringcateg) {

String count =jedis.hget("prodcnt:${product}",categ)

if(count== null|| "nil".equals(count))

return 0

return Integer.valueOf(count)

}

...

}

一个测试用例

在下边的小片段断中,你将模拟用户”1”的一些产品浏览记录,然后核实结果。注意在断言确定结果已经被存储到Redis之前你要等待两秒钟。(需要记住的是ProductCategoriesCounterBolt包含一个计数器的内存拷贝并且在后台将他们发送至Redis)。

package functional

class StatsTestextends AbstractAnalyticsTest{

@Test

public voidtestNoDuplication(){

navigate("1","0") // Players

navigate("1","1") // Players

navigate("1","2") // Players

navigate("1","3") // Cameras

Thread.sleep(2000)// Give two seconds for the system to process the data.

assertEquals 1,getProductCategoryStats("0","Cameras")

assertEquals 1,getProductCategoryStats("1","Cameras")

assertEquals 1,getProductCategoryStats("2","Cameras")

assertEquals 2,getProductCategoryStats("0","Players")

assertEquals 3,getProductCategoryStats("3","Players")

}

}

扩展性和可用性的说明

为适应本书一个单独章节的大小,该方案的架构被简化了。由于这个原因,你规避了一些对于这个方案的扩展和高可用性来说所必要的复杂性。该架构有两个主要的问题。

该架构中Redis服务器不仅仅是单点失败的而且是一个瓶颈。你只能获取Redis服务器所能处理的数据量。Redis层可以通过使用分片来扩展,并且它的可用性可以通过使用一个Master/Slave配置来改进,这需要topology和web应用资源都做出改变。

另一个弱点是以循环的方式添加机器时,web应用并没有成比例的扩展。这是因为当产品的统计改变的时候它需要被通知,并且是通知所有相应的浏览器。这个”通知浏览器”的桥接使用Socket.io实现,但它需要监听器和通知器被部署在同一台web服务器上。这只有在你共享GET /product/:id/stats 通信和 the POST /news 通信,并且都以相同的标准,确保引用相同产品的请求在相同的服务器上结束的情况下才做的到。

getting start with storm 翻译 第六章 part-4相关推荐

  1. Gradle2.0用户指南翻译——第六章. 构建脚本基础

    翻译项目请关注Github上的地址: https://github.com/msdx/gradledoc 本文翻译所在分支: https://github.com/msdx/gradledoc/tre ...

  2. 《Real-Time Rendering 4th Edition》读书笔记--简单粗糙翻译 第六章 纹理 Texturing

    写在前面的话:因为英语不好,所以看得慢,所以还不如索性按自己的理解简单粗糙翻译一遍,就当是自己的读书笔记了.不对之处甚多,以后理解深刻了,英语好了再回来修改.相信花在本书上的时间和精力是值得的. -- ...

  3. 计算机专业英语2013影印版翻译第六章,计算机专业英语2013影印版重点翻译.docx...

    计算机专业英语2013影印版重点翻译 第一章Computer competency refers to acquiring computer-related skills-indispensable ...

  4. 《Fundamentals Of Computer Graphics》虎书第三版翻译——第六章 矩阵变换

    线性代数的机制可以用来表达在3D场景中排列对象.用摄像机观察它们并将它们放到屏幕上所需的许多操作.几何变换,如旋转.平移.缩放和投影可以通过矩阵乘法来完成,而用于实现这一目的的变换矩阵是本章的主题.我 ...

  5. Introduction to Graph Neural Network翻译-第六章 图循环网络

    还有一种趋势是在传播步骤中使用来自rnn的门机制,如GRU [Cho et al., 2014]或LSTM [Hochreiter and Schmidhuber, 1997],以减少普通GNN模型的 ...

  6. 【编译原理复习】第六章---- 属性文法和语法制导翻译

    第六章 属性文法和语法制导翻译 本章主要掌握下面一些内容. 1.语义规则的两种描述方法:语法制导的定义和翻译方案.语法制导的定义没有指明语义规则的计算次序,而翻译方案显式给出语义规则( 或叫语义动作) ...

  7. 三万五千字长文!让你懂透编译原理(六)——第六章 属性文法和语法制导翻译

    三万五千字长文!让你懂透编译原理(六)--第六章 属性文法和语法制导翻译 长文预警 系列文章传送门: 万字长文+独家思维导图!让你懂透编译原理(一)--第一章 引论 万字长文!让你懂透编译原理(二)- ...

  8. Gradle 2.0 用户指南翻译——第五十六章. 多项目构建

    本文禁止w3cschool转载! 翻译项目请关注Github上的地址:https://github.com/msdx/gradledoc . 本文翻译所在分支:https://github.com/m ...

  9. [翻译] 神经网络与深度学习 第六章 深度学习 - Chapter 6 Deep learning

    目录: 首页 译序 关于本书 关于习题和难题 第一章 利用神经网络识别手写数字 第二章 反向传播算法是如何工作的 第三章 提升神经网络学习的效果 第四章 可视化地证明神经网络可以计算任何函数 第五章 ...

  10. Gradle 1.12用户指南翻译——第五十六章. 多项目构建

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

最新文章

  1. 华为AR28-11路由器配置
  2. log4j中调试与错误日志分开_idea中log4j日志插件报错
  3. 汇编 加法减法指令 inc dec add sub neg 标志寄存器测试
  4. Python爬虫如何去抓取qq音乐的歌手数据?
  5. iOS 深拷贝和浅拷贝
  6. java io内存泄露_java内存泄露和OutOfMemory
  7. 牛客题霸 [栈和排序] C++题解/答案
  8. 实现字符串的编码转换,用以解决字符串乱码问题
  9. 通过Java代码浅谈HTTP协议
  10. pip install flask-mongoengine报错
  11. 数通手稿留档——Multicast
  12. Git配置信息相关命令
  13. Java中native方法的使用
  14. C语言 全局变量和局部变量的区别
  15. 计算机程序设计艺术 pdf版
  16. QuickCHM V2.6
  17. 如何用计算机进行文件夹整理,如何对电脑文件进行分类整理,试试下面这四个步骤...
  18. 微型计算机结构框图,微型计算机系统结构图.doc
  19. 解析大多数WordPress用户都选择托管虚拟主机的原因
  20. jq trigger

热门文章

  1. ctf-web-sql注入
  2. pcap文件linux怎么打开,pcap文件用什么打开
  3. 我的世界服务器无限矿区块指令,我的世界区块刷新指令 | 手游网游页游攻略大全...
  4. 计算器是不是电子计算机,计算器和计算机的区别?
  5. refprop物性库_refprop 9.1 下载-refprop(制冷剂物性查询运算软件)附中文教程 9.1 最新免费版 - 河东下载站...
  6. java常用类实验报告总结_【Java基础】java常用类实验总结
  7. c4d学习笔记-快捷键
  8. 一个完整的SPC案例—从特性分析到CPK计算
  9. Visual Basic 6.0精简版下载地址
  10. oracle分析函数大全非常详细