rmq

RocketMQ高性能之底层存储设计

我怕爱的太早我们不能终老 提交于 2020-04-14 19:30:31
【推荐阅读】微服务还能火多久?>>> 说在前面 RocketMQ在底层存储上借鉴了Kafka,但是也有它独到的设计,本文主要关注深刻影响着RocketMQ性能的底层文件存储结构,中间会穿插一点点Kafka的东西以作为对比。 例子 Commit Log,一个文件集合,每个文件1G大小,存储满后存下一个,为了讨论方便可以把它当成一个文件,所有消息内容全部持久化到这个文件中;Consume Queue:一个Topic可以有多个,每一个文件代表一个逻辑队列,这里存放消息在Commit Log的偏移值以及大小和Tag属性。 为了简述方便,来个例子 假如集群有一个Broker,Topic为binlog的队列(Consume Queue)数量为4,如下图所示,按顺序发送这5条内容各不相同消息。 发送消息 先简单关注下Commit Log和Consume Queue。 RMQ文件全貌 RMQ的消息整体是有序的,所以这5条消息按顺序将内容持久化在Commit Log中。Consume Queue则用于将消息均衡地排列在不同的逻辑队列,集群模式下多个消费者就可以并行消费Consume Queue的消息。 Page Cache 了解了每个文件都在什么位置存放什么内容,那接下来就正式开始讨论这种存储方案为什么在性能带来的提升。 通常文件读写比较慢,如果对文件进行顺序读写,速度几乎是接近于内存的随机读写

RMQ问题的ST算法

为君一笑 提交于 2020-03-30 08:22:27
ST(Sparse Table)算法的基本思想是,预先计算从起点A[i]开始长度为2的j次方(j=0,1...logn)的区间的最小值,然后在查询时将任何一个区间A[i..j]划分为两个预处理好的可能重叠的区间,取这两个重叠区间的最小值。 在预处理阶段,从起点A[i]开始,任何一个长度为2^j的区间都可以划分为两个长度2^(j-1)的区间,其中第一个区间的范围为: i...i+2^(j-1)-1 ;第二个区间的范围为: i+2^(j-1)...i+2^j-1 。用M[i,j]表示从A[i]开始,长度为2^j的区间(即A[i]...A[i+2^j-1])最小值对应的下标,那么 A[M[i,j]] = min{A[i...i+2^(j-1)-1], A[ i+2^(j-1)...i+2^j-1 ]} 。 利用DP思想,先计算M[i,j-1]的值,然后计算M[i,j]的值。 在 查询阶段,任何区间A[i..j]的长度d=j-i+1,令k=floor(logd),那么该区间可以被两个长度为2^k的子区间完全覆盖,这两个长度 为2^k的区间可以有重叠。由于这两个区间已经在预处理中求得最小值,因此可以取二者的最小值得到A[i..j]的最小值。 ST算法预处理阶段的复杂度为O(nlogn),查询阶段的复杂度为O(1)。 实现: /** * * Using ST(Sparse Table)

poj 3264

落花浮王杯 提交于 2020-03-30 08:22:01
1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。这两个问题是在实际应用中经常遇到的问题,下面介绍一下解决这两种问题的比较高效的 算法 。当然,该问题也可以用线段树(也叫区间树)解决,算法复杂度为:O(N)~O(logN),这里我们暂不介绍。 2.RMQ算法 对于该问题,最容易想到的解决方案是遍历,复杂度是O(n)。但当数据量非常大且查询很频繁时,该算法无法在有效的时间内查询出正解。 本节介绍了一种比较高效的在线算法(ST算法)解决这个问题。所谓在线算法,是指用户每输入一个查询便马上处理一个查询。该算法一般用较长的时间做预处理,待信息充足以后便可以用较少的时间回答每个查询。ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。 (一)首先是预处理,用动态规划(DP)解决。 设A[i]是要求区间最值的数列,F[i, j]表示从第i个数起连续2^j个数中的最大值。(DP的状态) 例如: A数列为:3 2 4 5 6 8 1 2 9 7 F[1,0]表示第1个数起,长度为2^0=1的最大值,其实就是3这个数。同理 F

RMQ算法模板

◇◆丶佛笑我妖孽 提交于 2020-03-30 08:21:36
2、 RMQ算法(转载) 对于该问题,最容易想到的解决方案是遍历,复杂度是O(n)。但当数据量非常大且查询很频繁时,该算法也许会存在问题。 本节介绍了一种比较高效的在线算法(ST算法)解决这个问题。所谓在线算法,是指用户每输入一个查询便马上处理一个查询。该算法一般用较长的时间做预处理,待信息充足以后便可以用较少的时间回答每个查询。ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。 首先是预处理,用动态规划(DP)解决。设A[i]是要求区间最值的数列,F[i, j]表示从第i个数起连续2^j个数中的最大值。例如数列3 2 4 5 6 8 1 2 9 7,F[1,0]表示第1个数起,长度为2^0=1的最大值,其实就是3这个数。 F[1,2]=5,F[1,3]=8,F[2,0]=2,F[2,1]=4……从这里可以看出F[i,0]其实就等于A[i]。这样,DP的状态、初值都已经有了,剩下的就是状态转移方程。我们把F[i,j]平均分成两段(因为f[i,j]一定是偶数个数字),从i到i+2^(j-1)-1为一段,i+2^(j-1)到i+2^j-1为一段(长度都为2^(j-1))。用上例说明,当i=1,j=3时就是3,2,4,5 和 6,8,1,2这两段。F[i,j

RMQ (Range Minimal Query) 问题 ,稀疏表 ST

眉间皱痕 提交于 2020-03-30 08:21:12
RMQ ( 范围最小值查询 ) 问题是一种动态查询问题,它不需要修改元素,但要及时回答出数组 A 在区间 [l, r] 中最小的元素值 。 RMQ(Range Minimum/Maximum Query):对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。 对于 RMQ ,我们通常关心两方面的算法效率:预处理时间和查询时间。 解决一般 RMQ 问题的三种方法 胜者树 (Winner Tree) O(n)-O(logn) 稀疏表 (Sparse Table) O(nlogn)-O(1) 线段树 (Segment Tree) O(n)-O(logn) 这里介绍一个稀疏表算法。 一、稀疏表ST算法--预处理 二、稀疏表ST算法--查询 三、RMQ ST模板 package ads; public class RMQ_ST { int[] a; int[][] st;//st[i][j],i表示数组a的索引为i的元素,即i:索引 int n; public RMQ_ST(int[] a) { this.a = a; this.n = a.length; st = new int[n][17]; } void initRMQ() { int k = (int)(Math.log((double)n) / Math.log(2.0

每日进步一点点:解读消息中间件—RabbitMQ(集群原理与搭建篇)

亡梦爱人 提交于 2020-03-17 22:51:53
摘要:实际生产应用中都会采用消息队列的集群方案,如果选择RabbitMQ那么有必要了解下它的集群方案原理 一般来说,如果只是为了学习RabbitMQ或者验证业务工程的正确性那么在本地环境或者测试环境上使用其单实例部署就可以了,但是出于MQ中间件本身的可靠性、并发性、吞吐量和消息堆积能力等问题的考虑,在生产环境上一般都会考虑使用RabbitMQ的集群方案。 对于RabbitMQ这么成熟的消息队列产品来说,搭建它并不难并且也有不少童鞋写过如何搭建RabbitMQ消息队列集群的博文,但可能仍然有童鞋并不了解其背后的原理,这会导致其遇到性能问题时无法对集群进行进一步的调优。本篇主要介绍RabbitMQ集群方案的原理,如何搭建具备负载均衡能力的中小规模RabbitMQ集群,并最后给出生产环境构建一个能够具备高可用、高可靠和高吞吐量的中小规模RabbitMQ集群设计方案。 一、RabbitMQ集群方案的原理 RabbitMQ这款消息队列中间件产品本身是基于Erlang编写,Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现)。因此,RabbitMQ天然支持Clustering。这使得RabbitMQ本身不需要像ActiveMQ、Kafka那样通过ZooKeeper分别来实现HA方案和保存集群的元数据。集群是保证可靠性的一种方式

RMQ问题 Page 41 ST算法

时光怂恿深爱的人放手 提交于 2020-03-11 14:43:02
RMQ问题 Page 41 ST算法 http://www.51nod.com/Challenge/Problem.html#!#problemId=1174 第一次写博客 这是51nod上一个简单的基础题。 大致题意:给一组数组 让你判断T个 [ l , r ] [l,r] [ l , r ] 区间里的最大值(或最小值)。 分析 :暴力肯定会TLE。 根据倍增思想,需要引入2的整数次幂用来简化时间和空间,那么具体该怎么做呢? 先取数组 d p [ i ] [ j ] dp[i][j] d p [ i ] [ j ] ,表示从 i i i 开始的 2 j 2^j 2 j 个数中的最大值,即区间 [ i , i + 2 j − 1 ] [i,i+2^j-1] [ i , i + 2 j − 1 ] 。 接下来很容易理解的转移方程, 从 i i i 开始的 2 j 2^j 2 j 个数中的最大值肯定是其左半段和右半段的最大值 ,这个左半段和右半段完美契合2的整数次幂思想,只需要把幂次-1即可! dp [ i ] [ j ] = max ( dp [ i ] [ j - 1 ] , dp [ i + 1 << ( j - 1 ) ] [ j - 1 ] ) ; 预处理代码如下: void ST ( ) { for ( int i = 1 ; i <= n ; i ++ ) dp [ i

区间第K大值与RMQ问题

泄露秘密 提交于 2020-02-26 23:13:24
这次我们讨论一下有关区间中的值的问题。如果你只想看RMQ,请跳过下面这几段,在第一段代码的后面有详细的讲解。 在竞赛中,我们经常遇到最值问题。但是出题者往往给我们出一些这样的题目,让我们找到第K优解,而不是最优,比如K小生成树、K优背包等等。这篇文章主要介绍另一个“K问题“,区间第K大值。 区间第K大值的题意很明确,对于一个区间,找到其中第K大的一个数输出。这个问题可以用O(n 2 )的算法枚举,但是当区间很大的时候这种方法就会很费时。我们还可以将区间内的序列排序,直接输出a[k+l-1](l是区间左端点)即可。 我们知道,快排的原理是找到一个标准点,然后进行交换、分组,直到它的左边(以递增为例)都比它小,右边都比它大为止。但是结合这道题来说,每进行一遍分 组,第K大值就会确定的位于其中一组,或者就是那个标准点。然后我们只用将有第K大值的那个组再进行分组、查找(不是标准点),或者直接输出标准点(正好是标准点)。这样,我们就可以以少于1/2的操作找到我们想要的数。 对于多次询问,我们要保留下原始序列,以免之后再寻找时出现错误。 给出一道比较水的题,大家可以试一下~ 【题目描述】(rqnoj350)给出一个长度为N的序列A1,A2,A3,...,AN,其中每项都是小于10^5的自然数。现在有M个询问,每个询问都是Ai...Aj中第k小的数等于多少。数据范围:在60%的数据中,1≤N

数据结构——ST表(RMQ)

六眼飞鱼酱① 提交于 2020-02-17 17:58:34
ST表类似树状数组、线段树。 适用于解决区间最值得查询得算法,预处理O(nlogn),查询上ST表为O(1),而线段树为O(logn)。但是ST表只能除了离线的,不能修改。 ST表得构造采用DP的思想。主体为一个二维数组st[][],s[i][j] 表示 [i, i + 2^j - 1]区间的最值。 转移方程为: st[i][j] = min(st[i][j-1], st[i+2^(j-1)][j-1]) 。当然也可以是最大值。 接下来就是查询操作。 一般情况下查询的区间[a, b]不会满足正好[i, i+2^(j-1) ],那么就要将区间分为俩个(可能一头一尾会有重叠),[a,a+2^k -1]和[b - 2^k +1, b]。 k = floor(log(b-a+1)/log(2))。 ans = (st[a][k], st[b-(1<<k) + 1][k])。 习题: 1.luogu p3865 ST板子题 链接 : luogu p3865 题意 :n个数,m次查询, 每次查询给一个区间,让你求该区间里面的最大值。 代码 : # include <bits/stdc++.h> using namespace std ; const int maxn = 1e5 + 50 ; int n , m ; int a [ maxn ] ; int st [ maxn ] [ 20 ]

POJ3728 THE MERCHANT LCA RMQ DP

旧巷老猫 提交于 2020-02-12 20:25:58
题意简述:给定一个N个节点的树,1<=N<=50000 每个节点都有一个权值,代表商品在这个节点的价格。商人从某个节点a移动到节点b,且只能购买并出售一次商品,问最多可以产生多大的利润。 算法分析:显然任意两个城市之间的路径是唯一的,商人有方向地从起点移动到终点。询问这条路径上任意两点权值之差最大为多少,且要保证权值较大的节点在路径上位于权值较小的节点之后。 暴力的方法是显而易见的,只要找到两个点的深度最深的公共祖先,就等于找到了这条路径,之后沿着路径走一遍即可找到最大的利润,然而无法满足50000的数据规模。 首先考虑高效寻找LCA(公共祖先)的方法。记录ance[i][j]为节点i向上走2^j步到达的某个祖先。可以简单地列出方程 ance[i][j]=ance[ance[i][j-1]][j-1];于是找到了高效构建的方法。 每次寻找LCA 首先将两个节点通过swim(a,b)函数转移到同一深度,然后每次找一个最小的j使得ance[a][j]==ance[b][j] 之后将节点a赋值为ance[a][j-1] 直到j=0就找到了两者的LCA 现在我们已经找到了高效寻找LCA的方法,假设我们知道节点a到LCA的最小值minp[],LCA到节点b的最大值maxp[], 以及买卖地点全在LCA之前可以获得的最大利润maxi[] 以及买卖地点全在LCA之后可以获得的最大利润maxI[]