getting start with storm 翻译 第六章 part-4

转载请注明出处: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 通信,并且都以相同的标准,确保引用相同产品的请求在相同的服务器上结束的情况下才做的到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/352317.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Phpstorm调试详解(包含命令行以及浏览器)

2019独角兽企业重金招聘Python工程师标准>>> 运行环境 PHP版本:5.5.12 Phpstorm : 9.0.2 xdebug : 2.2.5 下载地址,请下载与当前PHP版本对应的版本 系统平台:Windows 7 一 ,要先给php安装xdebug扩展 1,…

windows核心编程之进程(3)

获取系统版本的函数: GetVersion返回一个DWORD类型的值,高子返回MS-DOS版本号,低字返回windows版本号 本来按照逻辑来说应该是低字的高字节返回windows的主版本号,低字节返回此版本号,但是编写该代码程序员犯了一个小错误&#…

2023CCPC河南省赛 VP记录

感觉现在的xcpc,风格越来越像CF,不是很喜欢,还是更喜欢多点算法题的比赛 VP银了,VP银也是银 感觉省赛都是思维题,几乎没有算法题,感觉像打了场大型的CF B题很简单没开出来,一直搞到最后&…

大学计算机专业 学习Python学习路线图(最新版)

这是我刚开始学习python时的一套学习路线,从入门到上手。(不敢说精通,哈哈~) 希望对大家有帮助哈~ 大家需要高清得完整python学习路线可以 一、Python入门、环境搭建、变量、数据类型 二、数据库编程 三、Linux系统 四、网页编…

哪些手机待办事项软件可以记录备忘并设置提醒?

当下手机软件的种类那么多,为什么有那么多人使用手机待办事项软件呢?原因很简单,因为这类软件可以记录备忘并设置提醒,非常适合哪些喜欢提前规划待办事项的人使用。但是,面对如此多的手机待办事项软件,具体…

【HTML】第 2 节 - HTML 标签

欢迎来到博主 Apeiron 的博客,祝您旅程愉快 ! 时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、标题标签 3、段落标签 4、文本格式化标签 5、图像标签 5.1、基本作用 5.2、属性 6、超链接标签 7、音频标…

Vivado下时序逻辑模块的仿真

文章目录 D触发器两级D触发器带异步复位的D触发器带异步复位和同步置数的D触发器移位寄存器单口RAM伪双口RAM真双口RAM单口ROM 组合逻辑电路在逻辑功能上特点是任意时刻的输出仅仅取决于当前时刻的输入,与电路原来的状态无关。 时序逻辑在逻辑功能上的特点是任意时刻…

单元测试方法-cmockery实践

目录 单元测试概念 引子 定义 内容 方法 单元测试模型 测试模型构建 单元测试工具简介 Cmockery使用介绍 简介 使用 VPBX实践 UT框架搭建 目录 编译: 实例demo 例1: 例2: 例3: 例4: 例5&#xff…

从0开始搭建vue3+vite+ts+pinia项目

目录 项目搭建选项 项目搭建步骤 本地开发环境 Vite脚手架构建项目 关联Git仓库 开发工具 安装pinia 安装Sass 安装Vant-UI 安装postcss-pxtorem(移动端项目) 安装axios 本地调试 环境变量 本地代理 全局UI组件 路由中间件 项目部署 n…

layui(2)----页面元素

水平导航栏 依赖加载模块&#xff1a;element <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport"…

AcWing 回转游戏 dfs IDA* 剪枝 统一操作 java

&#x1f351; 算法题解专栏 &#x1f351; 回转游戏 如下图所示&#xff0c;有一个 # 形的棋盘&#xff0c;上面有 1 , 2 , 3 1,2,3 1,2,3 三种数字各 8 8 8 个。 给定 8 8 8 种操作&#xff0c;分别为图中的 A s i m H A \\sim H AsimH。 这些操作会按照图中字母和箭头…

MCGS昆仑通态触摸屏导入博途自定义数据类型和DB块变量的具体方法演示

MCGS昆仑通态触摸屏导入博途自定义数据类型和DB块变量的具体方法演示 如下图所示,在博途中新建项目后,添加自己所需的数据类型,然后选中该数据类型,右击选择“从块生成源“—”仅所选块“, 如下图所示,设置文件名后点击保存, 如下图所示,选中需要导出的DB块,右击选…

vue 自定义el-table穿梭框功能

一、需求描述&#xff1a;前段时间接到一个需求是点击做一个类似穿梭框的表格点击选中功能&#xff0c;弹框的左边是全部数据展示&#xff0c;点击表格行数据可以选中自动增加到右边的已选框&#xff0c;并且可以手动删除、重置选中数据。点击确定后到展示到主页面&#xff0c;…

Java核心知识点常考面试题(持续更新中)

Java核心知识点常考面试题&#xff08;持续更新中&#xff09; 线程与线程池Java锁机制轻量级锁重量级锁 线程与线程池 一、线程 1、线程的状态 2、线程的创建方式 &#xff08;1&#xff09;继承 Thread 类&#xff1b; &#xff08;2&#xff09;实现 Runnable 接口&#…

IDEA2023.1配置Git

一、前言 在使用新设备整理git项目时&#xff0c;报了以下问题&#xff0c;在整理项目的同时&#xff0c;做下记录。 二、下载git 2.1.官网下载git 官网下载地址&#xff1a; git官网&#xff0c;如下图所示&#xff1a; 如果选方法二&#xff0c; 接下来会让选择系统&#…

【cocos精品】《三国之刃》:腾讯首款三国炫技格斗手游

基于cocos引擎开发的《三国之刃》是腾讯独家代理的三国题材的动作格斗手游。独创的自由组合战技系统&#xff0c;配合特色的兵器和灵兽技能&#xff0c;可搭配出上万种格斗套路&#xff0c;让您的战斗酣畅淋漓又变幻莫测。清爽灵活的操作&#xff0c;无锁定技术PK&#xff0c;更…

java开发街机三国志_入坑必看《街机三国志》游戏初期重点讲解

《街机三国志》为了让新手更好的了解游戏&#xff0c;设立里相关的新手指引&#xff0c;引导新入门的玩家完成各种任务与基础的系统教学。只凭新手教学是没办法在初期阶段积累足够的资源的。本次小编特意整理了一些新手教程中没有提及的重点&#xff0c;希望帮助玩家们更好的开…

搜索引擎三国鼎立:百度 vs 360 vs 搜狗

理论上说&#xff0c;搜索市场不存在平分秋色的可能&#xff0c;不管份额如何接近&#xff0c;最终必然是东风压倒西风&#xff0c;这一点在全球市场都未见过反例。雅虎在日本和台湾独占鳌头&#xff0c;Naver在韩国有压倒性优势&#xff0c;Yandex称霸俄罗斯。谷歌在全球大部分…

街机三国志隐藏人物刘备_隐藏的人物

街机三国志隐藏人物刘备 最初的程序员的故事将永远不为人知 背后没有外套的男人是梅尔凯&#xff08;Mel Kaye&#xff09;&#xff0c;埃德纳瑟&#xff08;Ed Nather&#xff09;为他写了他永恒的程序员绝版经典著作《故事》 。 那一年是1960年&#xff0c;尽管存在有关他编…

Java霸王的大陆梦幻版_三国志霸王的大陆,喜欢三国的进

三国是中国历史上英雄辈出的时代&#xff0c;《霸王的大陆》这款移植自Fc的战棋游戏更是中国手游java游戏的No.1!该游戏内容极其丰富&#xff0c;对玩家的要求很高&#xff0c;因此这完全是一款符合游戏高手要求的大型单机游戏。以下是这款游戏的核心攻略&#xff0c;只要稍加留…