当前位置:首页 > ZBLOG > 正文

zblog使用redis(zblog应用中心)

本篇文章给大家谈谈zblog使用redis,以及zblog应用中心对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

redis怎么使用

应用Redis实现数据的读写,同时利用队列处理器定时将数据写入mysql。

同时要注意避免冲突,在redis启动时去mysql读取所有表键值存入redis中,往redis写数据时,对redis主键自增并进行读取,若mysql更新失败,则需要及时清除缓存及同步redis主键。

这样处理,主要是实时读写redis,而mysql数据则通过队列异步处理,缓解mysql压力,不过这种方法应用场景主要基于高并发,而且redis的高可用集群架构相对更复杂,一般不是很推荐。

Redis应该怎么使用

推荐使用项目名:业务名称:时间构成,如:baike:login-name-code:20201228,百科项目登录验证码,与不同的开发人员定义相同时间的概率很低,时间可以按照不同情况定义到天、时、分、秒。

风控系统实践之感: drools 和 redis

需求:

开发一个风控系统,系统包括, 规则引擎和计算引擎, 主要的内容如下:

1. 规则的增删改和实时生效, 规则的分类执行

2. 按照一定的纬度计算累计值,比如按照 IP, 用户 id, 账户 等纬度。

3. 需要支持滑动窗口,滚动窗口,长度窗口等

遇到的问题主要有以下几点:

1. redis 做流计算太过勉强,一是根据业务上的需求,需要统计的key 至少有几亿个,最多也有几十亿个,另外redis 中需要存储少量的交易的信息。估算下来量也是非常可观

2. redis 中 hot key 特别明显,比如按照商户的纬度去统计,如果不对商户的key 进行拆封,像盒马那种流量的商户,对redis 的压力是非常大的。

我们采用的是redis 的cluster 模式,这样的话redis hot key 对redis 影响会更大。对其进行拆分是非常必要的,比如 按照小时拆分。 

3. 流式计算中,一个是乱序导致累加的计算不准确(有负值),另外一个是消息延迟. 当时我们尝试使用flink 中的水印的概念去解决问题,发现并不适合。这个坑也是我们实践过后才发现的。

最痛苦的经历是乱序和延迟消息的解决,现在是采取纠正的方式解决。

规则引擎

规则引擎我们选用了drools,简单的探索了drools core, drools DRL, drools CEP 等,但是回头看看,针对drools的使用缺点还是很多, 而且很明显,暂时还没有替换的打算. 

1. 使用 drools CEP 如何做分布式? 我们发现drools CEP中的几种窗口都是内存计算的,应用到分布式中就没有很好的办法,几乎做不到,除非drools 也去集成redis等这种分布式缓存。

2. 使用drools 觉得很笨重,因为依赖比较多,二是我们只用到了 drools 中的 if else 等判断,许多其它的功能基本就用不到,因为 1 中解决不了分布式的问题。所以从这点来说drools 已经废了,根本不用在创建kiesession 这种 重量级的东西。

3. drools中支持的运算符不是特别充分,比如像 log 运算,sum, max, avg 这种的运算等都是不支持的. DRL 语言对业务人员来说不是非常的友好。

4. 另外drools 中的 连续,非连续的规则,没有看出来如何配置,至少flink cep 是有这样API的。

综上所描述,不得不吐槽下 drools真是无语,也许了解的很简单,还有别的方式,另外drools workbench 也是很无语,很复杂,估计drools 厂商想通过这种方式挣钱。

总体感觉,如果有别的选择,最好不要选用drools,分布式的问题没有解决,就等于废了,因为各种分布式窗口都需要我们自己去实现。怎么办呢? 

规则引擎最后还是采用了drools,根据具体的业务含义创建不同的kiesession,  drools 起到了if else 判断的作用,至于滚动窗口,长度窗口和滑动窗口都通过redis来做计算。遇到头疼的问题,是

1. 根据不同的统计纬度,大概计算了下,需要几十亿个key,在redis 中做计算

2. 滑动窗口暂时靠 redis的zsort 的数据结构,性能不是非常好

3. 热点key 的问题,特别对于大商户的热点key 的问题,需要做拆分,拆分起来是比较复杂的

4. 消息延迟和消息乱序问题。

所以计算引擎的需求一般是

1. 计算很快,大几百个规则,能够很快的计算出准确的结果来

2. 计算准确率,当面对乱序和延迟消息的时候,如何计算的更加准确

3. 计算的量的问题,正如前面提到的,几十亿个key,另外还需要存储一些信息,计算的中间状态等,如何在redis 中丢失,就会造成计算不准确。

基于以上的问题,关键是如何做的更好,优化的更好,说实话,我没有找到答案,可以做的就是不断的优化redis 计算(暂时不能上大数据,比如flink, spark 等),减少redis 的操作带来的网络开销。

其实最后还要提一下,如果能采用内存计算,不用分布式计算,会不会速度更快点,比如根据业务来做分片,这样在各个实例统计的中间值就不用汇总,那么每个实例只需要内存计算就好,不需要访问redis而带来的网络开销。但是这样做也会带来架构层面的调整,比如 如何做 fault tolerance, 如何做 状态持久化, 等一系列的问题。 

从使用redis结果来看,效果也不是那么差,不考虑非常热点key 的情况下,最高tps 也达到6000多(2 台机器,16core,32G 内存), 一般公司的业务其实是可以满足的,对于非常热点的key,后续的优化是继续拆分.

一个好的风控系统是非常难的,做以笔记,以希望不断成长

通过redis的有序集合[zset] 实现延迟队列

php使用redis的有序集合zset实现延迟队列

我们通过redis的有序集合zset来实现简单的延迟队列,将消息数据序列化,作为zset的基本元素,把 消息生产时间戳 + 消息处理延迟时间戳 作为score,每次通过zRangeByScore获取一条消息进行处理,后通过zRem删除集合元素:相当于移除需要消费的 Job。

优点:

缺点:

1.不适合延迟时间高的业务场景。延迟时间可能有几秒钟的误差。

2.不适合大型项目 ,大型项目建议使用rabbitmq的延迟i消息队列

下面是简单的实现demo

Redis 实战 —— 10. 实现内容搜索、定向广告和职位搜索

通过改变程序搜索数据的方式,并使用 Redis 来减少绝大部分基于单词或者关键字进行的内容搜索操作的执行时间。 P154

倒排索引 (inverted indexes) 是互联网上绝大部分搜索引擎使用的底层结构,它类似于书本末尾的索引。倒排索引从每个被索引的文档里面提取一些单词,并记录包含每个单词的文档集合。 P154

示例

假设有三个文档:

我们就能得到下面的倒排索引集合:

检索的条件 "what", "is" 和 "it" 将对应这个集合: {0,1} ∩ {0,1,2} ∩ {0,1,2} = {0,1}

可以发现 Redis 的集合和有序集合非常适合处理倒排索引。

基本索引操作

从文档里面提取单词的过程通常被成为语法分析 (parsing) 和标记化 (tokenization) ,这个过程可以产生一系列用于表示文档的标记 (token) ,有时又被成为单词 (word) 。 P155

标记化的一个常见的附加步骤就是移除非用词 (stop word) 。非用词就是那些在文档中频繁出现却没有提供相应信息量的单词,对这些单词进行搜索将返回大量无用的结果。 P155

本书中实现方向索引的逻辑非常简单:

如果需要支持中文等,就不能简单进行英文分词,需要分词器进行处理。第一次接触倒排索引是在 Elasticsearch 中,感兴趣的可以了解 Elasticsearch 中倒排索引的实现以及 IK 中文分词器。

基本搜索操作

在索引里面查找一个单词是非常容易的,只需要获取单词集合里面的所有文档即可。根据多个单词查找文档时,就需要根据条件处理对应的集合,再从最终集合中获取所有文档。 P156

可以使用 Redis 的集合操作完成对不同条件的处理:

通过以上三类命令,我们基本能实现条件大部分的与或非操作。

分析并执行搜索

我们使用的查询语句进行分词后具有以下特征:

即: "connect +connection chat -proxy -proxies" 表示查询的文档需要包含 "connect" 或 "connection" ,同时也要包含 "chat" ,并且不能包含 "proxy" 和 "proxies" 。

实际处理时,先对同义词组分别取并集,然后与需要查询的单词一起取交集,最后与不希望包含的单词取差集,这样所得到的集合就是用户查询的结果集。

上述搜索功能以及能够搜索出用户查询的所有文档唯一标识的集合,现在我们将根据这个文档唯一标识集合以及每个文档的具体信息进行排序分页。

对于这种情况我们可以使用 Redis 的 SORT 命令对文档唯一标识集合通过引用每个文档的具体信息进行排序分页。 ( 05. Redis 其他命令简介 )

上面介绍了使用 Redis 进行搜索,并通过引用存储在 HASH 里面的数据对搜索结果进行排序分页。接下来将介绍利用集合和有序集合实现基于多个分值的复合排序操作,它能提供比 SORT 命令更高的灵活性。 P162

假设我们目前需要根据文档对更新时间和得票数进行排序,为此我们需要用两个有序集合存储相关信息。这两个有序集合的成员都是文档唯一标识,成员的分值则分别是文档的更新时间和得票数。

设经过搜索后满足搜索条件的文档唯一标识集合为 filtered_doc_ids ,文档唯一标识及其更新时间对应的有序集合为 doc_ids_with_update ,文档唯一 标识及其得票数对应的有序集合为 doc_ids_with_votes 。那么可以通过 ZINTERSTORE 命令对这三个集合求交集,最后得出的满足搜索条件的文档唯一标识及其排序分值对应的有序集合,再使用 ZRANGE , ZREVRANGE 进行分页获取即可。 P162

示例: ZINTERSTORE filtered_doc_ids_with_sort_score 3 filtered_doc_ids doc_ids_with_update doc_ids_with_votes WEIGHTS 0 {update_weight} {vote_weight}

其中:

所思

这种利用分值的方法很巧妙,基本可以实现多字段排序,但是优先级可能难以掌控,难以做到先按照某一字段排序,再按照另一字段排序的形式。因为每个字段对应的分值的数量级可能差别比较小,这个时候如果需要有排序字段的优先级,那么可能需要对每个权重进行精巧地设计才行。

上面介绍了使用有序集合对多个数值字段进行排序,由于有序集合的分值只能是浮点数,所以非数值字段不能直接用于排序,需要转换成对应的浮点数。但由于双精度浮点数只有 64 个二进制位,实际能使用 63 个二进制位,所以能表示的字符串并不多,只能使用字符串的前几个字符进行分值估计,不足指定字符数的需要补齐到指定字符数。当然如果字符集缩小的话,可以重新进行编码计算,进而可以对更长的字符串进行分值估计。 P165

当这个分值特别大的时候,可能会引发最终计算的分值溢出而出错的问题。

接下来将介绍使用集合和有序集合构建出一个几乎完整的广告服务平台 (ad-serving platform) 。 P166

针对广告的索引操作和针对其他内容的索引操作并没有太大的不同,被索引的的广告通常都拥有像位置、年龄和性别这类必需的定向参数,并且往往只会返回单个广告。 P167

广告的价格 P167

为了尽可能简化广告价格的计算方式,将对所有类型的广告进行转换,使得它们的价格可以基于每千次展示进行计算,产生出一个估算 CPM (estimated CPM, eCPM) 。 P168

将广告插入倒排索引 P169

我们基本可以复用上面提到的搜索功能,除了会将广告的关键词插入倒排索引,还会将广告的定向参数(位置、年龄和性别等)插入倒排索引中,并记录广告的类型、基本价格和 eCPM 价格。 P169

当系统收到广告定向请求的时候,它要做的就是在匹配用户定向参数的一系列广告里面,找出 eCPM 最高的那一个广告。同时,程序还会记录页面内容与广告内容的匹配程度,以及不同匹配程度对广告点击通过率的影响等统计数据。通过使用这些统计数据,广告中与页面相匹配的那些内容就会作为附加值被计入 CPC 和 CPA 的 eCPM 价格,使得那些包含了匹配内容的广告能够更多地被展示出来。 P170

计算附加值

计算附加值就是基于页面内容和广告内容两者之间匹配的单词,计算出应该给广告的 eCPM 价格加上多少增量。每个单词都有一个有序集合,成员为广告 id ,成员的分值为当前单词对这则广告的 eCPM 的附加值。 P171

在寻找合适的广告时,我们首先会过滤出匹配定位位置且至少包含一个页面单词的广告,然后通过计算附加值的方法替代搜索,以便实现每次投放价值最高的广告,并能够根据用户的行为学习。同时由于每个广告匹配的内容不同,最优方式应该是使用加权平均值来计算单词部分的附加值,但限于 Redis 本身的命令,我们最终采取 (max + min) / 2 的形式计算单词部分的附加值(max 表示所有匹配单词的最大附加值, min 表示所有匹配单词的最小附加值),采用如下命令即可: ZUNIONSTORE final_score 3 base max min WEIGHTS 1 0.5 0.5 。

从用户行为中学习 P175

首先需要存储用户的浏览记录,包括三部分:(每 100 次就主动更新一次 eCPM ) P175

其次需要存储用户的点击和动作记录,用于计算 点击通过率 = 点击量或动作次数 / 广告展示次数。(每次都更新 eCPM) P176

最后就是更新 eCPM ,包括两部分:

接下来将使用集合和有序集合实现职位搜索功能,并根据求职者拥有技能来为他们寻找合适的职位。 P180

第一反应肯定是直接对每一个求职者搜索所有的岗位,从而找到求职者合适的岗位。但这种方法效率极低(大部分岗位肯定是技能对不上的),而且无法进行性能扩展。 P181

使用类似上面提到的附加值形式,每次添加一个岗位时,在对应的技能集合中添加这个岗位的 id ( SADD idx:skill:{skill} {job_id} ),再在岗位有序集合中进行添加,成员为岗位 id ,成员的分值为所需的技能数量 ( ZADD job_required_skill_count {job_id} {required_skill_count} )。搜索的时候就先对求职者所有技能对应的集合使用 ZUNIONSTORE 操作计算每个公司匹配的技能数量 ( ZUNIONSTORE matched {n} idx:skill:{skill} ... WEIGHTS 1 ... ),然后再与岗位有序集合求交集,并让公司有序集合的权重为 -1 ( ZINTERSTORE result 2 job_required_skill_count matched WEIGHTS -1 1 ),最后获取分值为 0 的所有岗位即可完成搜索。 P181

所思

书上的这个方法比较麻烦,其实可以使用文章最开始的无序倒排索引,岗位相当于要搜索的文档,岗位所需的技能相当于单词。

Redis集群操作

有 slots

无 slots 时直接删除

(5)学习redis-trib命令使用:

添加两个节点

docker-compose.yaml 添加

1 create :创建一个集群环境host1:port1 ... hostN:portN(集群中的主从节点比例)

2 call :可以执行redis命令

3 add-node :将一个节点添加到集群里,第一个参数为新节点的ip:port,第二个参数为集群中任意一个已经存在的节点的ip:port

4 del-node [host:port node_id] :移除一个节点

5 reshard :重新分片

6 check [hosts:port]:检查集群状态

步骤一:使用add-node命令:绿色为新增节点,红色为已知存在节点

输出如下:

步骤二:查看集群状态:

注意: 当添加节点成功以后,新增的节点不会有任何数据,因为它没有分配任何的slot(hash槽)。我们需要为新节点手工分配slot。

步骤一:使用redis-trib命令,找到集群中的任意一个主节点(红色位置表现集群中的任意一个主节点),对其进行重新分片工作。

输出如下:

1提示一:是希望你需要多少个槽移动到新的节点上,可以自己设置,比如200个槽。

2提示二:是你需要把这200个slot槽移动到那个节点上去(需要指定节点id),并且下个 提示是输入all为从所有主节点(7001 7002 7003)中分别抽取响应的槽数(一共为200个槽到指定的新节点中!,并且会打印执行分片的计划。)

3提示三:输入yes确认开始执行分片任务。在最后我们再次看一下集群状态:

如上图所示,现在我们的7007已经有slot槽了,也就是说可以在7007上进行读写数据啦!到此为止我们的7007已经加入到集群中啦,并且是主节点(Master)

步骤一:还是需要执行add-node命令:

提示添加成功后我们继续看一下集群的状态:

如图所示,还是一个master节点,没有被分配任何的slot槽。

步骤二:我们需要执行replicate命令来指定当前节点(从节点)的主节点id为哪个。

首先需要登录新加的7008节点的客户端,然后使用集群命令进行操作,把当前的7008(slave)节点指定到一个主节点下(这里使用之前创建的7007主节点,红色表示节点id)

我们继续看一下当前集群的状态,如下图:我们已经成功的把7008放到7007这个主节点下面了,到此为止我们已经成功的添加完一个从节点了。

(9)我们可以对集群进行操作,来验证下是否可以进行读写(当然可以)。

(10)我们现在尝试删除一个节点(7008 slave)

步骤一:删除从节点7008,输入del-node命令,指定删除节点ip和端口,以及节点id(红色为7008节点id)

输出如下:

步骤二:再次查看一下集群状态,如下图所示,我们已经成功的移除了7008 slave节点,另外我们发现移除一个节点以后,当前节点的服务进程也会随之销毁。可以使用ps命令查看当前的服务(ps -el | grep redis),发现少了一个运行的server,也就是刚移除的7008从节点。

(11)最后,我们尝试删除之前加入的主节点7007,这个步骤会相对比较麻烦一些,因为主节点的里面是有分配了slot槽的,所以我们这里必须先把7007里的slot槽放入到其他的可用主节点中去,然后再进行移除节点操作才行,不然会出现数据丢失问题。

步骤一:删除7007(master)节点之前,我们需要先把其全部的数据(slot槽)移动到其他节点上去(目前只能把master的数据迁移到一个节点上,暂时做不了平均分配功能)。

输出如下:

到此为止我们已经成功的把7007主节点的数据迁移到7001上去了,我们可以看一下现在的集群状态如下图,你会发现7007下面已经没有任何数据(slot)槽了,证明迁移成功!

输出如下:

最后:我们查看集群状态,一切还原为最初始状态啦!OK 结束!

关于zblog使用redis和zblog应用中心的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

取消
扫码支持 支付码