-
#华为云开年采购季#15+云原生产品全场低至3折,新客1.98元起! -Redis低至6折,Kafka、RabbitMQ、RocketMQ等低至5.5折,3年5折! -数字资产链新客119元起,华为链新客19.8元起! -软件开发生产线CodeArts,新客试用1.98元起! -漏洞扫描、二进制成分分析、APP合规检测6.6折起! -Serverless应用引擎CAE,新客试用109元起! -ROMAConnect集成平台,打通新老应用,试用19.8元起! 下单抽FreeBuds无线耳机!更多产品优惠戳:http://t.cn/A6a7JhLQ 活动有效期至2023年3月31日,上云正当时!>点击这里,马上进入活动专场<
-
怎么配置redis外网指定的ip访问?相信大部分人都还没学会这个技能,为了让大家学会,给大家总结了以下内容,话不多说,一起往下看吧。 # bind 192.168.1.100 10.0.0.1 # bind 192.168.1.8 # bind 127.0.0.1修改完成后,需要重新启动redis服务。redis-server redis.conf如果iptables 没有开启6379端口,用这个方法开启端口命令:/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT保存防火墙修改命令:/etc/rc.d/init.d/iptables save通过iptables 允许指定的外网ip访问修改 Linux 的防火墙(iptables),开启你的redis服务端口,默认是6379。//只允许127.0.0.1访问6379iptables -A INPUT -s 127.0.0.1 -p tcp --dport 6379 -j ACCEPT//其他ip访问全部拒绝iptables -A INPUT -p TCP --dport 6379 -j REJECT未配置拒绝前配置拒绝后另外一种方式是通过bind方式启用上文描述的就是配置redis外网并指定ip访问redis服务的方法,具体使用情况还需要大家自己动手实验使用过才能领会。原文链接:https://www.yisu.com/zixun/145042.html
-
本文不为Redis安装和使用范畴,有兴趣的朋友可以联系我,也可以自行百度:Redis安装和使用 Redis实现缓存添加,更新和删除的方法有很多. 1:较为笨拙的方法,也是最稳定的方法,也是一些自动化缓存更新的原理但是代码就多了点,在需要用到缓存的地方,去判断, 先从缓存取,取不到,去数据库查找,找到返回该数据,并写入缓存 2:使用aop的思想,在需要用到缓存的地方左上标识(用注解实现即可,方法很多),剩下的原理同上,这是个一劳永逸的过程 3:就是这篇文章要讲的:使用spring自带的Cacheable注解处理Redis缓存,以下为具体的细节描述 1)使用maven项目管理 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.6.RELEASE</version> </dependency> 2)在需要使用到的地方加上Cacheable注解 cacheable能够实现自动缓存接口的返回结果,所以我们可以把注解直接加到我们需要缓存结果的接口上。 放的位置可以试service也可以是dao,以下是放到service和dao层的示例: 放到service层上: @Cacheable(value="workDetailV150",key="'workDetailV150'.concat(#param.workId.toString()).concat(#param.userId.toString())") public CliDresserWorkDetailV150 getWorkDetail(CliGetWorkDetailParam param) throws Exception { return doGetWorkDetail(param); } 放到dao层上: @Cacheable(value="getWorkDetailPhotos",key="'getWorkDetailPhotos'.concat(#root.args[0])") List<String> getWorkDetailPhotos(Integer workId); 有没有看到,两者的不同,在dao层上,因为用了mybatis的缘故,这里只有接口,那么用workId放到key里面是存不到redis的,因为spring cache拿到的是null。所以这里必须用#root.args[x]的方式设置。 问题来了,那个这里有一个value还有一个key,他们分别代表了什么呢? 3)缓存的清除 如果我们缓存的实体更新了,怎么办?不能够get的还是旧的东西。这时候就需要强制清除相关联的缓存了。方法就是提供一个空的接口方法,在该方法上添加@CacheEvict的注解,如下: @CacheEvict(value = "workDetailV150", allEntries=true) public void evictWorkDetailCache(){ } 4)Cacheable注解key的说明 这个地方主要简单说明一下3个要素:1.字符串、2.接口参数、3.环境参数,以及一个函数 字符串很好说了用单引号括起来就可以了。 接口参数直接用#加参数名,如果是参数内的属性那么继续用.串联接好了。 环境参数: 属性名称 描述 示例 methodName 当前方法名 root.methodName method 当前方法 root.method.name target 当前被调用的对象 root.target targetClass 当前被调用的对象的class root.targetClass args 当前方法参数组成的数组 root.args[0] caches 当前被调用的方法使用的Cache root.caches[0].name 最后是关键函数concat,意思很明白了,就是连接字符串用的。 使用过程,或者有什么不明白的,我们可以互相讨论,共同进步!欢迎大家骚扰~~~ ———————————————— 原文链接:https://blog.csdn.net/u011271894/article/details/77969070
-
#华为云11.11# 实惠更实用·“11”都如愿云中间件、DevSecOps、数字资产管理年度钜惠,多重福利来袭!福利一:全场低至3折,新客试用1.98元起!福利二:领万元礼包,15+款产品券后低至5.8折!福利三:下单抽好礼,有机会获FreeBuds耳机!福利四:新购满额送,华为P50 Pro等好礼等你拿!现在上云,一惠到底!活动有效期至2022年11月30日,上云正当时!>点击这里,马上进入活动专场<
-
安装和配置Redis 前言:windows没有32位的Redis,所以32位机器的朋友考虑换一下机器。 1、windows环境下的redis需要去github上获取: https://github.com/MicrosoftArchive/redis/releases 2、直接下载最新版本,选择.msi格式的安装版本(另外一种.zip通过命令安装) 3、直接运行.msi的安装包,一直next,直到下面界面,勾选上再next 4、这一步选择端口,然后next(后面可以通过配置文件修改的) 5、选择最大缓存容量,点击next(后面可以通过配置文件修改的) 6、接下来可以点击install进行安装了,安装完毕后,进入redis安装目录找到配置文件,注意是redis.windows-service.conf,不是redis.windows.conf,后者是以非系统服务方式启动程序使用的配置文件. 7、在配置文件中,找到requirepass foobared字样,在其后面追加一行,输入requirepass 123456。这是访问Redis时所需的密码,一般测试情况下可以不用设定密码。不过,即使是作为本地访问,也建议设定一个密码。此处以简单的123456来演示,然后保存退出 8、进入计算机服务中(右键计算机-->管理-->服务和应用程序-->服务),再在右侧找到Redis名称的服务,查看启动情况。如未启动,则手动启动之。正常情况下,服务应该正常启动并运行了,但是因为前面修改过配置文件,需要重启服务,切记 9、测试一下redis能否正常工作。用命令进入redis安装路径,输入redis-cli并回车(redis-cli是客户端程序)如图正常提示进入,并显示正确端口号,则表示服务已经启动。 10、使用服务前需要先通过密码验证。输入“auth 123456”并回车(123456是之前设定的密码)。返回提示OK表示验证通过。 然后再验证set和get。一切正常,说明可以开始随便盘它了。 可视化工具 redis常用的可视化工具 Redis Desktop Manager。 下载地址:https://github.com/uglide/RedisDesktopManager/releases/download/0.9.3/redis-desktop-manager-0.9.3.817.exe 这位朋友的百度云盘里也有(感谢):https://blog.csdn.net/u012688704/article/details/82251338 下载完成之后直接点击安装包安装即可,无需任何配置。 然后直接连接Redis就可以盘了 ———————————————— 原文链接:https://blog.csdn.net/weixin_41381863/article/details/88231397
-
工作中需要同步GaussDB(for opengauss)中的档案数据到redis,有没有什么好的方案,华为有提供相应的工具吗?
-
安装和配置Redis前言:windows没有32位的Redis,所以32位机器的朋友考虑换一下机器。1、windows环境下的redis需要去github上获取:https://github.com/MicrosoftArchive/redis/releases2、直接下载最新版本,选择.msi格式的安装版本(另外一种.zip通过命令安装)3、直接运行.msi的安装包,一直next,直到下面界面,勾选上再next4、这一步选择端口,然后next(后面可以通过配置文件修改的)5、选择最大缓存容量,点击next(后面可以通过配置文件修改的)6、接下来可以点击install进行安装了,安装完毕后,进入redis安装目录找到配置文件,注意是redis.windows-service.conf,不是redis.windows.conf,后者是以非系统服务方式启动程序使用的配置文件.7、在配置文件中,找到requirepass foobared字样,在其后面追加一行,输入requirepass 123456。这是访问Redis时所需的密码,一般测试情况下可以不用设定密码。不过,即使是作为本地访问,也建议设定一个密码。此处以简单的123456来演示,然后保存退出8、进入计算机服务中(右键计算机-->管理-->服务和应用程序-->服务),再在右侧找到Redis名称的服务,查看启动情况。如未启动,则手动启动之。正常情况下,服务应该正常启动并运行了,但是因为前面修改过配置文件,需要重启服务,切记9、测试一下redis能否正常工作。用命令进入redis安装路径,输入redis-cli并回车(redis-cli是客户端程序)如图正常提示进入,并显示正确端口号,则表示服务已经启动。10、使用服务前需要先通过密码验证。输入“auth 123456”并回车(123456是之前设定的密码)。返回提示OK表示验证通过。然后再验证set和get。一切正常,说明可以开始随便盘它了。可视化工具redis常用的可视化工具 Redis Desktop Manager。0.9.4以上要给钱的。下载地址:https://github.com/uglide/RedisDesktopManager/releases/download/0.9.3/redis-desktop-manager-0.9.3.817.exe这位朋友的百度云盘里也有(感谢):https://blog.csdn.net/u012688704/article/details/82251338下载完成之后直接点击安装包安装即可,无需任何配置。然后直接连接Redis就可以盘了————————————————原文链接:https://blog.csdn.net/weixin_41381863/article/details/88231397
-
【摘要】 用户画像存储是推荐业务核心,但开源Redis无法胜任。华为云高斯Redis是最佳存储选型,轻松降本60%,同时获得企业级高稳定性。本文分享自华为云社区《华为云GaussDB(for Redis)揭秘第23期:用GaussDB(for Redis)存画像,推荐业务轻松降本60%》,作者: 高斯Redis官方博客 。一、什么是推荐系统 不知道大家有没有过这样的经历,当你前脚刚在某电商网站买了一个手机,过两天之后你再打开该电商网站,显示在首页的上必定有耳机、手机壳和蓝牙音箱等手机配件。如果你买的不是手机,而是一件衣服的话,下次打开显示的必定是和该衣服非常搭配的裤子和鞋子等。聪明的你不禁要问,为何电商网站如此强大,竟然能提前预知你的偏好,并且给你推荐你可能喜欢的商品?其实在这背后,都离不开那强大的推荐系统。 什么是推荐系统呢?首先我们来看看维基百科对推荐系统的定义:推荐系统是一种信息过滤系统,可以根据用户历史行为用于预测用户对物品的“评分”或“偏好”。简单来说,如果你是一个电子发烧友,那么系统肯定会给你推荐各种新鲜出炉的3C产品,如果你是一个coder,那么你的页面肯定充斥各种编程大全的书籍。推荐系统近年来非常流行,应用于各行各业,它推荐的对象包括:电影、音乐、新闻、书籍、学术论文、搜索查询、分众分类、电商购物和游戏业务等。二、推荐系统的架构 了解了什么是推荐系统之后,接下来我们继续介绍下推荐系统的架构,以游戏行业为例,一个典型的游戏业务中的推荐系统架构设计如下: 推荐系统主要由3部分组成,分别是:行为日志收集、特征生产和特征消费。(1)行为日志收集 大数据业务收集用户的行为日志,分析获得用户画像,并且将这些用户画像保存在分布式文件系统HDFS中。(2)特征生产 工程业务负责为大数据业务提供一套接口调用,主要是“灌库”,即定时或按一定逻辑把HDFS中的用户画像加工成特征,灌入工程业务负责的“KV存储”。(3)特征消费 工程业务团队还负责将算法团队的推荐模型进行工程落地,他们开发线上推理组件,从KV存储中提取特征数据,分析计算,最终得出推荐结论,展示给用户。三、推荐系统的存储痛点 上一节中我们介绍了游戏行业中推荐系统的架构,这也是推荐系统的一个典型架构。从架构图可以看出,KV存储在整套链路中,承载着重要的承上启下作用。然而,推荐系统中的KV存储却存在着两个大的痛点,第一个是成本高,第二个是扩容慢。(1)成本高 首先第一个是成本高的问题。通常我们搭建KV存储的话首选都是选择自建一个开源Redis集群作为KV存储系统。一方面,开源Redis的数据全部放在内存中,众所周知内存的存储成本是非常昂贵的,内存只适合用于存储少量数据,如果数据量大的话,数据的存储成本将成为企业的负担;另一方面由于开源Redis在进行AOF文件重写的过程中,存在fork机制,导致开源Redis在AOF文件重写时,其内存利用率只有50%,这就进一步使增加了开源Redis的内存使用成本。(2)扩容慢 除了成本比较高,开源Redis还存在扩容慢的问题。在自建的开源Redis集群中,随着业务增长,KV存储的容量不得不进行扩容。但是由于原生Redis本身的架构特点,在扩容过程中难免要发生key的跨slot迁移,如下图所示: 如果发生slot迁移,需要耗时很久并且业务受影响时间长。四、为什么推荐高斯Redis 上一节中我们介绍了推荐系统的存储痛点,如何解决呢?要解决这两个痛点,无非是需要进行降本增效,而高斯Redis似乎就是为了解决这些问题而生。(1)降本 就降本而言,高斯Redis从两个方面降低KV数据的存储成本: 第一个方面,高斯Redis的所有数据全部落在磁盘,相比开源Redis存在内存中而言,其成本降低了75%~90%,拥有极大的价格优势。举个例子来说,一个512GB的开源Redis集群,其成本几乎要5w/月,而相同规格的实例,如果替换成高斯Redis,其成本节约40%以上,几乎节省了一个人力成本在里面。下面这张表格是不同层级的存储器之间的成本对比图。 另一方面,在推荐系统中,KV数据库主要存储的是用户画像的信息,而这些信息基本上都是经过Protobuf序列化后的信息,而高斯Redis自带的数据压缩功能,对序列化后的信息可以进行高压缩比的压缩,相对于开源Redis而言,存储空间仅仅为开源Redis的70%到85%,这又进一步降低了KV数据的存储成本。(2)增效 除了降本,另一方面就是增效了。众所周知,开源Redis的架构中,如下图所示,其存储和计算是不分离的,这就导致节点进行扩容的时候,会发生分片的迁移,从而导致业务会受到影响。 高斯Redis为了解决这个问题,采用了存算分离的架构,如下图所示: 在采用存算分离的架构下,底层数据可以被任意上层计算节点访问,扩容过程不发生数据拷贝搬迁,速度极快。节点扩容时,分钟级完成,业务只有秒级感知。容量扩容时,业务0感知。无论是扩节点还是扩磁盘容量,对业务造成的影响几乎为0。五、总结 本文简单介绍了推荐系统是什么,并且以游戏行业中的推荐系统为例,介绍了推荐系统的架构和其存在的存储痛点,并且介绍了高斯Redis如何解决该存储痛点。在这个大数据时代,推荐系统的应用会越来越多,作为推荐系统的数据存储,高斯Redis解决了开源Redis所存在的缺点,为推荐系统提供了有力的技术支撑。六、附录本文作者:华为云数据库GaussDB(for Redis)团队杭州/西安/深圳简历投递:yuwenlong4@huawei.com更多产品信息,欢迎访问官方博客:bbs.huaweicloud.com/blogs/248875
-
随着互联网信息技术的发展个性化推荐早已融入我们的生活手机里收藏的各类资讯内容背后都有TA作为国内领先的内容生态服务平台,上海阅客信息科技有限公司(简称“阅客”)通过数据分析驱动运营,规模化提供内容生态服务,并基于内容场景提供广告技术服务,以技术精准匹配内容和用户,实现内容收益的最大化。阅客拥有强大的内容服务和广告能力,每日过万的内容更新以及上亿的曝光,庞大的数据体量和海量高并发,对支撑阅客业务应用的数据库发起了挑战。数据量激增下的存储问题数据库作为承载海量数据的基石,承担着守护企业数据资产的重任,也在企业数字化转型中发挥着关键作用。数据量激增下,阅客使用的基于ECS自建的Redis数据库在高并发和稳定性方面面临巨大压力,成本也随之攀升:性能问题 经常出现慢查询问题,每天有大量告警。专业分析:在配置缓存场景中,阅客使用了Redis存储配置策略信息。这里通常会存在一些大key,大key在开源Redis中经常有阻塞请求的性能问题。海量数据高并发访问业务经常出现访问超时,甚至需要重启自建Redis。同样,每天也会受到大量告警。专业分析:由于业务采用分布式部署,对Redis的并发请求量很大,自建sentinel哨兵Redis上连接数日常维持在3万,开源Redis无法承受。数据存储成本高昂 数据量激增,给业务运营带来压力,成本随之增加。专业分析:布隆过滤场景中的protobuf序列化数据也越来越多,增长到了TB级。而开源Redis内存成本痛点、稳定性痛点开始出现。搬迁兼容顾虑 如果选择上云,阅客必须修改自己的业务代码,然后重新发版、上线,业务改造负担大。专业分析:阅客一开始自建了两类不同架构的Redis集群,分别是Cluster集群和Sentinel集群。每个集群对应相应的客户端代码,且不互相支持。云原生时代的个性化推荐云原生时代,基于统一云基础设施的云原生数据库,成为企业上云首选。阅客紧随时代发展潮流,选择了华为云云原生数据库GaussDB(for Redis)作为企业数字化转型的数据底座,全数替换了原先自建的Redis数据库,业务发展迈上新台阶。性能卓越,内容推荐更快速针对阅客配置缓存业务中的性能问题,GaussDB(for Redis)采用分布式架构和多线程结合的方式,提供了卓越的性能,保障业务持续高效运行。相比开源Redis的单线程架构, GaussDB(for Redis)的多线程架构更具优势,即使存在大key,也不会导致全局性能受损。成功搬迁后,阅客自己的响应超时告警大幅减少,配置缓存业务响应及时高效,内容推荐更快速到达用户端。海量存储,内容推荐更平稳GaussDB(for Redis)提供独享的连接数资源,客户将自建哨兵Redis搬迁到4节点GaussDB(for Redis)实例后,业务实实在在独享4万连接数资源,且都在合适阈值内,运行非常稳定,彻底解决了阅客业务的连接数问题,亿级流量洪峰场景下也能从容面对,内容推荐更平稳。布隆过滤器业务成本节省80%GaussDB(for Redis)采用存算分离架构,可以独立购买计算、存储资源,避免开源Redis经常出现的算力成本浪费;拥有强大的数据压缩能力,尤其对布隆过滤场景中的protobuf序列化数据有奇效,实现了TB级数据到GB级的有效压缩,释放了80%的存储成本,完全超乎客户想象,也为客户今后的业务增长铺好了路。应用无须改造,一键式搬迁GaussDB(for Redis) 提供“Proxy通用型”实例类型,同时兼容StandAlone客户端、Cluster客户端以及Sentinel客户端,无需修改客户端业务代码,真正做到了“一种架构全兼容”、“业务搬迁0改造”,彻底打消了阅客的搬迁兼容顾虑。在研发团队支撑下,一周就搞定了全部数十套自建Redis,实现了高效平滑无感迁移。云原生数据库GaussDB(for Redis)不仅提升了阅客的服务效率,让个性化推荐更快更稳,还降低了存储和改造成本,为企业未来发展奠定了云化基础,助力阅客实现更高质量的资讯触达。转自华为云公众号
-
一、什么是推荐系统不知道大家有没有过这样的经历,当你前脚刚在某电商网站买了一个手机,过两天再打开该电商网站,首页推荐显示的必定有耳机、手机壳、蓝牙音箱等手机配件。如果你买的不是手机,而是一件衣服,那么下次打开电商网站显示的,必定是和衣服搭配的裤子和鞋子等。聪明的你不禁要问,为何电商网站如此强大,竟能提前预知你的偏好,并且给你推荐你可能喜欢的商品?其实在这背后,都离不开那强大的推荐系统。什么是推荐系统?首先我们来看看维基百科上的定义:推荐系统是一种信息过滤系统,可以根据用户历史行为预测用户对物品的“评分”或“偏好”。简单来说,如果你是一个电子发烧友,那么系统肯定会给你推荐各种新鲜出炉的3C产品,如果你是一个coder,那么你的页面肯定充满各种编程大全的书籍。推荐系统近年来非常流行,应用于各行各业,推荐的对象包括:电影、音乐、新闻、书籍、学术论文、搜索查询、分众分类、电商购物和游戏业务等。二、推荐系统的架构了解了什么是推荐系统之后,接下来我们继续介绍下推荐系统的架构,以游戏行业为例,一个典型的游戏业务的推荐系统架构设计如下: 推荐系统主要由3部分组成,分别是:行为日志收集、特征生产和特征消费。 01.行为日志大数据业务通过收集用户的行为日志,分析获得用户画像,并且将这些用户画像保存在分布式文件系统HDFS中。02.特征生产工程业务负责为大数据业务提供一套接口调用,主要是“灌库”,即定时或按一定逻辑把HDFS中的用户画像加工成特征,灌入工程业务负责的“KV存储”。 03.特征消费工程业务团队还负责将算法团队的推荐模型进行工程落地,他们开发线上推理组件,从KV存储中提取特征数据、分析计算,最终得出推荐结论,展示给用户。 三、推荐系统的存储痛点上一节中我们介绍了游戏行业中推荐系统的架构,这也是推荐系统的一个典型架构。从架构图可以看出,KV存储在整套链路中,承载着重要的承上启下作用。然而,推荐系统中的KV存储却存在着两个大的痛点,第一个是成本高,第二个是扩容慢。 01.成本高首先第一个是成本高的问题。通常我们搭建KV存储的首选是选择自建一个开源Redis集群作为KV存储系统。一方面,开源Redis的数据全部放在内存中,众所周知内存的存储成本非常昂贵,只适用于存储少量数据,如果数据量大,存储成本将成为企业的负担;另一方面,开源Redis在进行AOF文件重写的过程中存在fork机制,导致开源Redis在AOF文件重写时,其内存利用率只有50%,这就进一步使增加了开源Redis的内存使用成本。02.扩容慢除了成本比较高,开源Redis还存在扩容慢的问题,在自建的开源Redis集群中,随着业务增长,KV存储的容量不得不进行扩容。但由于原生Redis本身的架构特点,在扩容过程中难免要发生key的跨slot迁移,如下图所示,跨slot迁移需要耗时很久并且业务受影响时间长。 四、为什么推荐GaussDB(for Redis)知道了推荐系统的痛点所在,该如何解决呢?究其根本是降本增效,而GaussDB(for Redis)可以说是为解决这些问题而生。01.降本GaussDB(for Redis)从两个方面降低KV数据的存储成本: 第一个方面,GaussDB(for Redis)的所有数据全部落在存储,相比开源Redis数据存放在内存中,其成本降低了75%~90%,形成极大的价格优势。举个例子,一个512GB的开源Redis集群,其成本几乎要5w/月,而相同规格的实例,如果替换成GaussDB(for Redis),其成本节约40%以上,几乎节省了一个人力成本在里面。下面这张表格是不同层级存储器之间的成本对比图。 另一方面,在推荐系统中,KV数据主要存储的是用户画像的信息,这些信息基本上都是经过Protobuf序列化后的信息,而GaussDB(for Redis)自带的数据压缩功能,可以对序列化后的信息进行高压缩比的压缩,实际占用空间仅为开源Redis的50%左右,这又进一步降低了KV数据的存储成本。 02.增效除了降本,另一方面就是增效了。众所周知,开源Redis的架构中,如下图所示,其存储和计算是不分离的,这就导致节点进行扩容的时候,会发生分片的迁移,从而导致业务会受到影响。GaussDB(for Redis)为了解决这个问题,采用了存算分离的架构,如下图所示:在存算分离的架构下,底层数据可以被任意上层计算节点访问,扩容过程不发生数据拷贝搬迁,速度极快;同时还做到分钟级节点扩容,业务秒级感知;存储扩容业务0感知。无论是扩节点还是扩存储容量,对业务的影响几乎为0。五、总结本文简单介绍了推荐系统是什么,并以游戏业务为例,阐明了推荐系统的架构和存在的存储痛点,同时GaussDB(for Redis)是如何解决这些存储痛点的。在大数据时代,推荐系统的应用场景将会越来越多,作为推荐系统的数据存储,GaussDB(for Redis)完美弥补了开源Redis的短板,能够为推荐系统提供强有力的技术支撑。
-
【摘要】 2018年,王思聪的冲顶大会,西瓜视频的百万英雄,再到映客的芝士超人,直播答题火爆全网。我服务的一家电商公司也加入了这次热潮,技术团队研发了直播答题功能。答题结束之后,红包会以红包雨的形式落下,用户点击屏幕上落下的红包,若抢到红包,红包会以现金的形式进入用户账户。 红包雨是一个典型的高并发场景,短时间内有海量请求访问服务端,技术团队为了让系统运行顺畅,抢红包采用了基于 Redis + Lua...本文分享自华为云社区《红包雨中:Redis 和 Lua 的邂逅》,作者:勇哥java实战分享。2018年,王思聪的冲顶大会,西瓜视频的百万英雄,再到映客的芝士超人,直播答题火爆全网。我服务的一家电商公司也加入了这次热潮,技术团队研发了直播答题功能。答题结束之后,红包会以红包雨的形式落下,用户点击屏幕上落下的红包,若抢到红包,红包会以现金的形式进入用户账户。红包雨是一个典型的高并发场景,短时间内有海量请求访问服务端,技术团队为了让系统运行顺畅,抢红包采用了基于 Redis + Lua 脚本的设计方案。1 整体流程我们分析下抢红包的整体流程 :运营系统配置红包雨活动总金额以及红包个数,提前计算出各个红包的金额并存储到 Redis 中;抢红包雨界面,用户点击屏幕上落下的红包,发起抢红包请求;TCP 网关接收抢红包请求后,调用答题系统抢红包 dubbo 服务,抢红包服务本质上就是执行 Lua 脚本,将结果通过 TCP 网关返回给前端;用户若抢到红包,异步任务会从 Redis 中 获取抢得的红包信息,调用余额系统,将金额返回到用户账户。2 红包 Redis 设计抢红包有如下规则:同一活动,用户只能抢红包一次 ;红包数量有限,一个红包只能被一个用户抢到。如下图,我们设计三种数据类型:运营预分配红包列表 ;队列元素 json 数据格式 :1{2 //红包编号3 redPacketId : '365628617880842241' 4 //红包金额5 amount : '12.21' 6}用户红包领取记录列表;队列元素 json 数据格式:1{2 //红包编号3 redPacketId : '365628617880842241'4 //红包金额5 amount : '12.21',6 //用户编号7 userId : '265628617882842248'8}用户红包防重 Hash 表;抢红包 Redis 操作流程 :通过 hexist 命令判断红包领取记录防重 Hash 表中用户是否领取过红包 ,若用户未领取过红包,流程继续;从运营预分配红包列表 rpop 出一条红包数据 ;操作红包领取记录防重 Hash 表 ,调用 HSET 命令存储用户领取记录;将红包领取信息 lpush 进入用户红包领取记录列表。抢红包的过程 ,需要重点关注如下几点 :执行多个命令,是否可以保证原子性 , 若一个命令执行失败,是否可以回滚;在执行过程中,高并发场景下,是否可以保持隔离性;后面的步骤依赖前面步骤的结果。Redis 支持两种模式 : 事务模式 和 Lua 脚本,接下来,我们一一展开。3 事务原理Redis 的事务包含如下命令:序号命令及描述1MULTI 标记一个事务块的开始。2EXEC 执行所有事务块内的命令。3DISCARD 取消事务,放弃执行事务块内的所有命令。4WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。5UNWATCH 取消 WATCH 命令对所有 key 的监视。事务包含三个阶段:事务开启,使用 MULTI , 该命令标志着执行该命令的客户端从非事务状态切换至事务状态 ;命令入队,MULTI 开启事务之后,客户端的命令并不会被立即执行,而是放入一个事务队列 ;执行事务或者丢弃。如果收到 EXEC 的命令,事务队列里的命令将会被执行 ,如果是 DISCARD 则事务被丢弃。下面展示一个事务的例子。1redis> MULTI 2OK3redis> SET msg "hello world"4QUEUED5redis> GET msg6QUEUED7redis> EXEC81) OK91) hello world这里有一个疑问?在开启事务的时候,Redis key 可以被修改吗?在事务执行 EXEC 命令之前 ,Redis key 依然可以被修改。在事务开启之前,我们可以 watch 命令监听 Redis key 。在事务执行之前,我们修改 key 值 ,事务执行失败,返回 nil 。通过上面的例子,watch 命令可以实现类似乐观锁的效果 。4 事务的ACID4.1 原子性原子性是指:一个事务中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。第一个例子:在执行 EXEC 命令前,客户端发送的操作命令错误,比如:语法错误或者使用了不存在的命令。1redis> MULTI2OK3redis> SET msg "other msg"4QUEUED5redis> wrongcommand ### 故意写错误的命令6(error) ERR unknown command 'wrongcommand' 7redis> EXEC8(error) EXECABORT Transaction discarded because of previous errors.9redis> GET msg10"hello world"在这个例子中,我们使用了不存在的命令,导致入队失败,整个事务都将无法执行 。第二个例子:事务操作入队时,命令和操作的数据类型不匹配 ,入队列正常,但执行 EXEC 命令异常 。1redis> MULTI 2OK3redis> SET msg "other msg"4QUEUED5redis> SET mystring "I am a string"6QUEUED7redis> HMSET mystring name "test"8QUEUED9redis> SET msg "after"10QUEUED11redis> EXEC121) OK132) OK143) (error) WRONGTYPE Operation against a key holding the wrong kind of value154) OK16redis> GET msg17"after"这个例子里,Redis 在执行 EXEC 命令时,如果出现了错误,Redis 不会终止其它命令的执行,事务也不会因为某个命令执行失败而回滚 。综上,我对 Redis 事务原子性的理解如下:命令入队时报错, 会放弃事务执行,保证原子性;命令入队时正常,执行 EXEC 命令后报错,不保证原子性;也就是:Redis 事务在特定条件下,才具备一定的原子性 。4.2 隔离性数据库的隔离性是指:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别 ,分别是:未提交读(read uncommitted)提交读(read committed)可重复读(repeatable read)串行化(serializable)首先,需要明确一点:Redis 并没有事务隔离级别的概念。这里我们讨论 Redis 的隔离性是指:并发场景下,事务之间是否可以做到互不干扰。我们可以将事务执行可以分为 EXEC 命令执行前和 EXEC 命令执行后两个阶段,分开讨论。EXEC 命令执行前在事务原理这一小节,我们发现在事务执行之前 ,Redis key 依然可以被修改。此时,可以使用 WATCH 机制来实现乐观锁的效果。EXEC 命令执行后因为 Redis 是单线程执行操作命令, EXEC 命令执行后,Redis 会保证命令队列中的所有命令执行完 。 这样就可以保证事务的隔离性。4.3 持久性数据库的持久性是指 :事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。Redis 的数据是否持久化取决于 Redis 的持久化配置模式 。没有配置 RDB 或者 AOF ,事务的持久性无法保证;使用了 RDB模式,在一个事务执行后,下一次的 RDB 快照还未执行前,如果发生了实例宕机,事务的持久性同样无法保证;使用了 AOF 模式;AOF 模式的三种配置选项 no 、everysec 都会存在数据丢失的情况 。always 可以保证事务的持久性,但因为性能太差,在生产环境一般不推荐使用。综上,redis 事务的持久性是无法保证的 。4.4 一致性一致性的概念一直很让人困惑,在我搜寻的资料里,有两类不同的定义。维基百科我们先看下维基百科上一致性的定义:Consistency ensures that a transaction can only bring the database from one valid state to another, maintaining database invariants: any data written to the database must be valid according to all defined rules, including constraints, cascades, triggers, and any combination thereof. This prevents database corruption by an illegal transaction, but does not guarantee that a transaction is correct. Referential integrity guarantees the primary key – foreign key relationship.在这段文字里,一致性的核心是“约束”,“any data written to the database must be valid according to all defined rules ”。如何理解约束?这里引用知乎问题 如何理解数据库的内部一致性和外部一致性,蚂蚁金服 OceanBase 研发专家韩富晟回答的一段话:“约束”由数据库的使用者告诉数据库,使用者要求数据一定符合这样或者那样的约束。当数据发生修改时,数据库会检查数据是否还符合约束条件,如果约束条件不再被满足,那么修改操作不会发生。关系数据库最常见的两类约束是“唯一性约束”和“完整性约束”,表格中定义的主键和唯一键都保证了指定的数据项绝不会出现重复,表格之间定义的参照完整性也保证了同一个属性在不同表格中的一致性。“ Consistency in ACID ”是如此的好用,以至于已经融化在大部分使用者的血液里了,使用者会在表格设计的时候自觉的加上需要的约束条件,数据库也会严格的执行这个约束条件。所以事务的一致性和预先定义的约束有关,保证了约束即保证了一致性。我们细细品一品这句话: This prevents database corruption by an illegal transaction, but does not guarantee that a transaction is correct。写到这里可能大家还是有点模糊,我们举经典转账的案例。我们开启一个事务,张三和李四账号上的初始余额都是1000元,并且余额字段没有任何约束。张三给李四转账1200元。张三的余额更新为 -200 , 李四的余额更新为2200。从应用层面来看,这个事务明显不合法,因为现实场景中,用户余额不可能小于 0 , 但是它完全遵循数据库的约束,所以从数据库层面来看,这个事务依然保证了一致性。Redis 的事务一致性是指:Redis 事务在执行过程中符合数据库的约束,没有包含非法或者无效的错误数据。我们分三种异常场景分别讨论:执行 EXEC 命令前,客户端发送的操作命令错误,事务终止,数据保持一致性;执行 EXEC 命令后,命令和操作的数据类型不匹配,错误的命令会报错,但事务不会因为错误的命令而终止,而是会继续执行。正确的命令正常执行,错误的命令报错,从这个角度来看,数据也可以保持一致性;执行事务的过程中,Redis 服务宕机。这里需要考虑服务配置的持久化模式。无持久化的内存模式:服务重启之后,数据库没有保持数据,因此数据都是保持一致性的;RDB / AOF 模式: 服务重启后,Redis 通过 RDB / AOF 文件恢复数据,数据库会还原到一致的状态。综上所述,在一致性的核心是约束的语意下,Redis 的事务可以保证一致性。《设计数据密集型应用》这本书是分布式系统入门的神书。在事务这一章节有一段关于 ACID 的解释:Atomicity, isolation, and durability are properties of the database,whereas consistency (in the ACID sense) is a property of the application. The application may rely on the database’s atomicity and isolation properties in order to achieve consistency, but it’s not up to the database alone. Thus, the letter C doesn’t really belong in ACID.原子性,隔离性和持久性是数据库的属性,而一致性(在 ACID 意义上)是应用程序的属性。应用可能依赖数据库的原子性和隔离属性来实现一致性,但这并不仅取决于数据库。因此,字母 C 不属于 ACID 。很多时候,我们一直在纠结的一致性,其实就是指符合现实世界的一致性,现实世界的一致性才是事务追求的最终目标。为了实现现实世界的一致性,需要满足如下几点:保证原子性,持久性和隔离性,如果这些特征都无法保证,那么事务的一致性也无法保证;数据库本身的约束,比如字符串长度不能超过列的限制或者唯一性约束;业务层面同样需要进行保障 。4.5 总结我们通常称 Redis 为内存数据库 , 不同于传统的关系数据库,为了提供了更高的性能,更快的写入速度,在设计和实现层面做了一些平衡,并不能完全支持事务的 ACID。Redis 的事务具备如下特点:保证隔离性;无法保证持久性;具备了一定的原子性,但不支持回滚;一致性的概念有分歧,假设在一致性的核心是约束的语意下,Redis 的事务可以保证一致性。另外,在抢红包的场景下, 因为每个步骤需要依赖上一个步骤返回的结果,需要通过 watch 来实现乐观锁 ,从工程角度来看, Redis 事务并不适合该业务场景。5 Lua 脚本5.1 简介“ Lua ” 在葡萄牙语中是“月亮”的意思,1993年由巴西的 Pontifical Catholic University 开发。该语言的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua 脚本可以很容易的被 C/C ++ 代码调用,也可以反过来调用 C/C++ 的函数,这使得 Lua 在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替 XML, Ini 等文件格式,并且更容易理解和维护。Lua 由标准 C 编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的 Lua 解释器不过 200 k,在目前所有脚本引擎中,Lua 的速度是最快的。这一切都决定了 Lua 是作为嵌入式脚本的最佳选择。Lua 脚本在游戏领域大放异彩,大家耳熟能详的《大话西游II》,《魔兽世界》都大量使用 Lua 脚本。Java 后端工程师接触过的 api 网关,比如 Openresty ,Kong 都可以看到 Lua 脚本的身影。从 Redis 2.6.0 版本开始, Redis内置的 Lua 解释器,可以实现在 Redis 中运行 Lua 脚本。使用 Lua 脚本的好处 :减少网络开销。将多个请求通过脚本的形式一次发送,减少网络时延。原子操作。Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。复用。客户端发送的脚本会永久存在 Redis 中,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。Redis Lua 脚本常用命令:序号命令及描述1EVAL script numkeys key [key ...] arg [arg ...] 执行 Lua 脚本。2EVALSHA sha1 numkeys key [key ...] arg [arg ...] 执行 Lua 脚本。3SCRIPT EXISTS script [script ...] 查看指定的脚本是否已经被保存在缓存当中。4SCRIPT FLUSH 从脚本缓存中移除所有脚本。5SCRIPT KILL 杀死当前正在运行的 Lua 脚本。6SCRIPT LOAD script 将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。5.2 EVAL 命令命令格式:1EVAL script numkeys key [key ...] arg [arg ...]说明:script是第一个参数,为 Lua 5.1脚本;第二个参数numkeys指定后续参数有几个 key;key [key ...],是要操作的键,可以指定多个,在 Lua 脚本中通过KEYS[1], KEYS[2]获取;arg [arg ...],参数,在 Lua 脚本中通过ARGV[1], ARGV[2]获取。简单实例:1redis> eval "return ARGV[1]" 0 100 2"100"3redis> eval "return {ARGV[1],ARGV[2]}" 0 100 10141) "100"52) "101"6redis> eval "return {KEYS[1],KEYS[2],ARGV[1]}" 2 key1 key2 first second71) "key1"82) "key2"93) "first"104) "second"下面演示下 Lua 如何调用 Redis 命令 ,通过redis.call()来执行了 Redis 命令 。1redis> set mystring 'hello world'2OK3redis> get mystring4"hello world"5redis> EVAL "return redis.call('GET',KEYS[1])" 1 mystring6"hello world"7redis> EVAL "return redis.call('GET','mystring')" 08"hello world"5.3 EVALSHA 命令使用 EVAL 命令每次请求都需要传输 Lua 脚本 ,若 Lua 脚本过长,不仅会消耗网络带宽,而且也会对 Redis 的性能造成一定的影响。思路是先将 Lua 脚本先缓存起来 , 返回给客户端 Lua 脚本的 sha1 摘要。 客户端存储脚本的 sha1 摘要 ,每次请求执行 EVALSHA 命令即可。EVALSHA 命令基本语法如下:redis> EVALSHA sha1 numkeys key [key ...] arg [arg ...] 实例如下:redis> SCRIPT LOAD "return 'hello world'" "5332031c6b470dc5a0dd9b4bf2030dea6d65de91" redis> EVALSHA 5332031c6b470dc5a0dd9b4bf2030dea6d65de91 0 "hello world"5.4 事务 VS Lua 脚本从定义上来说, Redis 中的脚本本身就是一种事务, 所以任何在事务里可以完成的事, 在脚本里面也能完成。 并且一般来说, 使用脚本要来得更简单,并且速度更快。因为脚本功能是 Redis 2.6 才引入的, 而事务功能则更早之前就存在了, 所以 Redis 才会同时存在两种处理事务的方法。不过我们并不打算在短时间内就移除事务功能, 因为事务提供了一种即使不使用脚本, 也可以避免竞争条件的方法, 而且事务本身的实现并不复杂。-- https://redis.io/Lua 脚本是另一种形式的事务,他具备一定的原子性,但脚本报错的情况下,事务并不会回滚。Lua 脚本可以保证隔离性,而且可以完美的支持后面的步骤依赖前面步骤的结果。综上,Lua 脚本是抢红包场景最优的解决方案。但在编写 Lua 脚本时,要注意如下两点:为了避免 Redis 阻塞,Lua 脚本业务逻辑不能过于复杂和耗时;仔细检查和测试 Lua 脚本 ,因为执行 Lua 脚本具备一定的原子性,不支持回滚。6 实战准备我选择 Redisson 3.12.0 版本作为 Redis 的客户端,在 Redisson 源码基础上做一层薄薄的封装。创建一个 PlatformScriptCommand 类, 用来执行 Lua 脚本。// 加载 Lua 脚本 String scriptLoad(String luaScript); // 执行 Lua 脚本 Object eval(String shardingkey, String luaScript, ReturnType returnType, List<Object> keys, Object... values); // 通过 sha1 摘要执行Lua脚本 Object evalSha(String shardingkey, String shaDigest, List<Object> keys, Object... values);这里为什么我们需要添加一个 shardingkey 参数呢 ?因为 Redis 集群模式下,我们需要定位哪一个节点执行 Lua 脚本。public int calcSlot(String key) { if (key == null) { return 0; } int start = key.indexOf('{'); if (start != -1) { int end = key.indexOf('}'); key = key.substring(start+1, end); } int result = CRC16.crc16(key.getBytes()) % MAX_SLOT; log.debug("slot {} for {}", result, key); return result; }7 抢红包脚本客户端执行 Lua 脚本后返回 json 字符串。用户抢红包成功{ "code":"0", //红包金额 "amount":"7.1", //红包编号 "redPacketId":"162339217730846210" }用户已领取过{ "code":"1" }用户抢红包失败{ "code":"-1" }Redis Lua 中内置了 cjson 函数,用于 json 的编解码。-- KEY[1]: 用户防重领取记录 local userHashKey = KEYS[1]; -- KEY[2]: 运营预分配红包列表 local redPacketOperatingKey = KEYS[2]; -- KEY[3]: 用户红包领取记录 local userAmountKey = KEYS[3]; -- KEY[4]: 用户编号 local userId = KEYS[4]; local result = {}; -- 判断用户是否领取过 if redis.call('hexists', userHashKey, userId) == 1 then result['code'] = '1'; return cjson.encode(result); else -- 从预分配红包中获取红包数据 local redPacket = redis.call('rpop', redPacketOperatingKey); if redPacket then local data = cjson.decode(redPacket); -- 加入用户ID信息 data['userId'] = userId; -- 把用户编号放到去重的哈希,value设置为红包编号 redis.call('hset', userHashKey, userId, data['redPacketId']); -- 用户和红包放到已消费队列里 redis.call('lpush', userAmountKey, cjson.encode(data)); -- 组装成功返回值 result['redPacketId'] = data['redPacketId']; result['code'] = '0'; result['amount'] = data['amount']; return cjson.encode(result); else -- 抢红包失败 result['code'] = '-1'; return cjson.encode(result); end end脚本编写过程中,难免会有疏漏,如何进行调试?个人建议两种方式结合进行。编写 junit 测试用例 ;从 Redis 3.2 开始,内置了 Lua debugger(简称LDB), 可以使用 Lua debugger 对 Lua 脚本进行调试。8 异步任务在 Redisson 基础上封装了两个类 ,简化开发者的使用成本。RedisMessageConsumer : 消费者类,配置监听队列名,以及对应的消费监听器String groupName = "userGroup"; String queueName = "userAmountQueue"; RedisMessageQueueBuilder buidler = redisClient.getRedisMessageQueueBuilder(); RedisMessageConsumer consumer = new RedisMessageConsumer(groupName, buidler); consumer.subscribe(queueName, userAmountMessageListener); consumer.start();RedisMessageListener : 消费监听器,编写业务消费代码public class UserAmountMessageListener implements RedisMessageListener { @Override public RedisConsumeAction onMessage(RedisMessage redisMessage) { try { String message = (String) redisMessage.getData(); // TODO 调用用户余额系统 // 返回消费成功 return RedisConsumeAction.CommitMessage; }catch (Exception e) { logger.error("userAmountService invoke error:", e); // 消费失败,执行重试操作 return RedisConsumeAction.ReconsumeLater; } } }9 写到最后"纸上得来终觉浅, 绝知此事要躬行" 。学习 Redis Lua 过程中,查询了很多资料,一个例子一个例子的实践,收获良多。非常坦诚的讲 , 写这篇文章之前,我对 Redis Lua 有很多想当然的理解,比如 Redis 的事务不能回滚就让我惊讶不已。所以当面对自己不熟悉的知识点时,不要轻易下结论,以谦卑的心态去学习,才是一个工程师需要的心态。同时,没有任何一项技术是完美的,在设计和编码之间,有这样或者那样的平衡,这才是真实的世界。
-
【摘要】 GaussDB(for Redis)推出双活方案,助力全球化业务部署,为您的数据资产保驾护航!本文分享自华为云社区《华为云GaussDB(for Redis)揭秘第22期:拔掉电源会怎样?GaussDB(for Redis)双活让你有备无患》,作者: 高斯Redis官方博客。一、GaussDB(for Redis)双活方案介绍 数据库系统是业务稳定运行的基石,其重要性不言而喻。然而,现实世界存在着的如断电、火灾,甚至是更小概率的地震等突发灾害,这些不稳定因素都会威胁到公司核心业务的连续性。 华为云GaussDB(for Redis)是采用存算分离架构的企业级KV数据库,使用方式上完全兼容开源Redis,同时稳定性全面超越开源Redis,此外还提供数据高可靠存储、秒级在线扩容等企业级能力。 在上半年的故障演练中,作为需求方的某内部重要业务部门对华为云KV数据库GaussDB(for Redis)进行了一系列严苛的可靠性测试。其中就包括模拟实例级断电,评测GaussDB(for Redis)的双活容灾能力。在故障演练中,GaussDB(for Redis)顺利通过测试,满足了业务部门对RTO和RPO等指标的严格要求。GaussDB(for Redis)支持双活容灾,即在两个实例之间建立数据同步链路,其中主实例支持读写,备实例只读。适用于以下两类业务场景: 1. 灾备系统:核心业务生产环境可靠性要求高,例如金融服务等。 2. 实例级读写分离:有超高并发访问诉求,例如广告竞价、推荐系统等。 在后续规划中,GaussDB(for Redis)还将进一步支持双主实例模式,实现双主双写,敬请期待。下面让我们来深入了解GaussDB(for Redis)的双活能力。二、GaussDB(for Redis)双活原理及评估指标1) 架构解析 常见的容灾方案有以下2种:同城容灾:由于距离近,通信质量好,比较容易实现数据零丢失。一般用于防范火灾、供电故障等人为破坏引起的灾难。异地容灾:由于主备数据中心之间距离远,通常会有少量的数据丢失,而异地灾备可以防范火灾、水灾、建筑物破坏、地震、战争等可能遇到的风险隐患,保障业务的连续性。 GaussDB(for Redis)双活方案支持同城容灾和异地容灾,下图展示了其技术原理: 可以看出,与开源Redis那种简单的命令转发不同,GaussDB(for Redis)的双活方案是基于WAL日志的数据同步,原理上更类似于MySQL数据库。在双活架构中,RsyncServer进程负责数据的全量和增量同步。数据同步链路采用华为云内部高速网络,同Region内仅毫秒级延迟。 GaussDB(for Redis)的双活功能有以下企业级特性:全量同步:支持秒级快照,且不影响原有集群的正常读写,发送速度快增量同步:监听日志写入变更,实时同步最新数据,毫秒级延迟key保序:主备实例采用多线程异步并发模式发送数据,按Key保序可靠传输:利用wal日志序号的单调递增特性,实现滑窗机制确保可靠传输高效传输:日志迭代、网络发送、DB增删监听等任务采用Reactor事件管理,全流程pipeline异常重传:解决网络抖动导致的丢包或延迟现象断点续传:每个DB持久化保存其应答过的日志序号,如发生宕机、网络隔离、进程重启等情况,可从该序号位置进行续传防止回流:同步到对端流量做特殊标记,防止回流到源端2) 技术指标 从技术上看,业界衡量容灾系统有两个主要指标:RPO:最多可能丢失数据的时长。RTO:从灾难发生到整个系统恢复正常所需要的最大时长。 一般而言,容灾系统能够提供较好的RTO和RPO指标。国际通用的容灾系统的评审标准SHARE 78(7个层次、8个原则),可以作为广大用户衡量和选择容灾解决方案的指标。 目前,在大部分场景下,GaussDB(for Redis)灾备方案位于6级,即只有在极端场景下才会丢失少量数据。3) 优势总结 根据前期市场调研,有些客户的业务场景基于开源Redis搭建集群级的灾备系统,从技术原理上评估可靠性很低,违背了灾备的初衷。与之相比,GaussDB(for Redis)提供企业级可靠的双活方案,优势如下:三、GaussDB(for Redis)双活搭建步骤 登录GaussDB NoSQL控制台,您可以很方便地搭建GaussDB(for Redis)双活系统: 1. 点击“购买数据库实例”,创建2个GaussDB(for Redis)实例(主、备),建议规格保持相同。 2. 进行网络配置,详细指导:https://support.huaweicloud.com/redisug-nosql/nosql_10_0502.html 3. 选中期望的主实例,如图操作,开始搭建双活关系: 4. 在“搭建双活关系”页面,选中期望的备实例,点击确定,即开始双活系统搭建。 注意:一旦双活系统开始搭建,备实例数据将被清空,请谨慎操作。 双活关系搭建完成后,除了用于容灾之外,其备实例可提供读服务,可以有效分担主实例的读压力。四、GaussDB(for Redis)双活技术演进 当前双活方案中,备实例在运行期间仅提供读服务,如果两个数据中心能同时提供写服务,那么将极大地提高资源利用率。当灾难发生时,双活系统提供极致的RPO和RTO,从而最大程度保障业务连续性。它具有资源利用率高的特点,支持数据冲突解决等功能。目前,GaussDB(for Redis)的双活多写功能已经在开发阶段,不久之后即将上线,请大家拭目以待。五、附录本文作者:华为云数据库GaussDB(for Redis)团队杭州/西安/深圳简历投递:yuwenlong4@huawei.com更多产品信息,欢迎访问官方博客:bbs.huaweicloud.com/blogs/248875
-
【摘要】 高斯Redis 搭建业务二级索引,低成本,高性能,实现性能与成本的双赢本文分享自华为云社区《华为云GaussDB(for Redis)揭秘第21期:使用高斯Redis实现二级索引》,作者:高斯Redis官方博客。一、背景提起索引,第一印象就是数据库的名词,但是,高斯Redis也可以实现二级索引!!!高斯Redis中的二级索引一般利用zset来实现。高斯Redis相比开源Redis有着更高的稳定性、以及成本优势,使用高斯Redis zset实现业务二级索引,可以获得性能与成本的双赢。索引的本质就是利用有序结构来加速查询,因而通过Zset结构高斯Redis可以轻松实现数值类型以及字符类型索引。• 数值类型索引(zset按分数排序):• 字符类型索引(分数相同时zset按字典序排序): 下面让我们切入两类经典业务场景,看看如何使用高斯Redis来构建稳定可靠的二级索引系统。 二、场景一:词典补全当在浏览器中键入查询时,浏览器通常会按照可能性推荐相同前缀的搜索,这种场景可以用高斯Redis二级索引功能实现。2.1 基本方案最简单的方法是将用户的每个查询添加到索引中。当需要进行用户输入补全推荐时,使用ZRANGEBYLEX执行范围查询即可。如果不希望返回太多条目,高斯Redis还支持使用LIMIT选项来减少结果数量。• 将用户搜索banana添加进索引:ZADD myindex 0 banana:1• 假设用户在搜索表单中输入“bit”,并且我们想提供可能以“bit”开头的搜索关键字。ZRANGEBYLEX myindex "[bit" "[bit\xff"即使用ZRANGEBYLEX进行范围查询,查询的区间为用户现在输入的字符串,以及相同的字符串加上一个尾随字节255(\xff)。通过这种方式,我们可以获得以用户键入字符串为前缀的所有字符串。2.2 与频率相关的词典补全实际应用中通常希望按照出现频率自动排序补全词条,同时可以清除不再流行的词条,并自动适应未来的输入。我们依然可以使用高斯Redis的ZSet结构实现这一目标,只是在索引结构中,不仅需要存储搜索词,还需要存储与之关联的频率。• 将用户搜索banana添加进索引 • 判断banana是否存在ZRANGEBYLEX myindex "[banana:" + LIMIT 0 1 • 假设banana不存在,添加banana:1,其中1是频率ZADD myindex 0 banana:1 • 假设banana存在,需要递增频率 若ZRANGEBYLEX myindex "[banana:" + LIMIT 0 1 中返回的频率为1 1)删除旧条目:ZREM myindex 0 banana:1 2)频率加一重新加入:ZADD myindex 0 banana:2 请注意,由于可能存在并发更新,因此应通过Lua脚本发送上述三个命令,用Lua script自动获得旧计数并增加分数后重新添加条目。• 假设用户在搜索表单中输入“banana”,并且我们想提供相似的搜索关键字。通过ZRANGEBYLEX获得结果后按频率排序。ZRANGEBYLEX myindex "[banana:" + LIMIT 0 10 1) "banana:123" 2) "banaooo:1" 3) "banned user:49" 4) "banning:89"• 使用流算法清除不常用输入。从返回的条目中随机选择一个条目,将其分数减1,然后将其与新分数重新添加。但是,如果新分数为0,我们需从列表中删除该条目。 • 若随机挑选的条目频率是1,如banaooo:1ZREM myindex 0 banaooo:1 • 若随机挑选的条目频率大于1,如banana:123ZREM myindex 0 banana:123 ZADD myindex 0 banana:122 从长远来看,该索引会包含热门搜索,如果热门搜索随时间变化,它还会自动适应。三、场景二:多维索引除了单一维度上的查询,高斯Redis同样支持在多维数据中的检索。例如,检索所有年龄在50至55岁之间,同时薪水在70000至85000之间的人。实现多维二级索引的关键是通过编码将二维的数据转化为一维数据,再基于高斯Redis zset存储。从可视化视角表示二维索引。下图空间中有一些点,它们代表我们的数据样本,其中x和y是两个变量,其最大值均为400。图片中的蓝色框代表我们的查询。我们希望查询x介于50和100之间,y介于100和300之间的所有点。3.1 数据编码 若插入数据点为x = 75和y = 2001) 填充0(数据最大为400,故填充3位) x = 075 y = 2002) 交织数字,以x表示最左边的数字,以y表示最左边的数字,依此类推,以便创建一个编码 027050若使用00和99替换最后两位,即027000 to 027099,map回x和y,即: x = 70-79 y = 200-209因此,针对x=70-79和y = 200-209的二维查询,可以通过编码map成027000 to 027099的一维查询,这可以通过高斯Redis的Zset结构轻松实现。同理,我们可以针对后四/六/etc位数字进行相同操作,从而获得更大范围。3) 使用二进制为获得更细的粒度,可以将数据用二进制表示,这样在替换数字时,每次会得到比原来大二倍的搜索范围。假设我们每个变量仅需要9位(以表示最多400个值的数字),我们采用二进制形式的数字将是: x = 75 -> 001001011 y = 200 -> 011001000交织后,000111000011001010让我们看看在交错表示中用0s ad 1s替换最后的2、4、6、8,...位时我们的范围是什么:3.2 添加新元素 若插入数据点为x = 75和y = 200 x = 75和y = 200二进制交织编码后为000111000011001010,ZADD myindex 0 0001110000110010103.3 查询 查询:x介于50和100之间,y介于100和300之间的所有点从索引中替换N位会给我们边长为2^(N/2)的搜索框。因此,我们要做的是检查搜索框较小的尺寸,并检查与该数字最接近的2的幂,并不断切分剩余空间,随后用ZRANGEBYLEX进行搜索。下面是示例代码:def spacequery(x0,y0,x1,y1,exp) bits=exp*2 x_start = x0/(2**exp) x_end = x1/(2**exp) y_start = y0/(2**exp) y_end = y1/(2**exp) (x_start..x_end).each{|x| (y_start..y_end).each{|y| x_range_start = x*(2**exp) x_range_end = x_range_start | ((2**exp)-1) y_range_start = y*(2**exp) y_range_end = y_range_start | ((2**exp)-1) puts "#{x},#{y} x from #{x_range_start} to #{x_range_end}, y from #{y_range_start} to #{y_range_end}" # Turn it into interleaved form for ZRANGEBYLEX query. # We assume we need 9 bits for each integer, so the final # interleaved representation will be 18 bits. xbin = x_range_start.to_s(2).rjust(9,'0') ybin = y_range_start.to_s(2).rjust(9,'0') s = xbin.split("").zip(ybin.split("")).flatten.compact.join("") # Now that we have the start of the range, calculate the end # by replacing the specified number of bits from 0 to 1. e = s[0..-(bits+1)]+("1"*bits) puts "ZRANGEBYLEX myindex [#{s} [#{e}" } } end spacequery(50,100,100,300,6) 四、总结本文介绍了如何通过高斯Redis搭建二级索引,二级索引在电商、图(hexastore)、游戏等领域具有广泛的应用场景,高斯redis现网亦有很多类似应用。高斯Redis基于存算分离架构,依托分布式存储池确保数据强一致,可方便的支持二级索引功能,为企业客户提供稳定可靠、超高并发,且能够极速弹性扩容的核心数据存储服务。附录本文作者:华为云数据库GaussDB(for Redis)团队杭州/西安/深圳简历投递:yuwenlong4@huawei.com更多产品信息,欢迎访问官方博客:bbs.huaweicloud.com/blogs/248875
-
文末附件可下载《GaussDB(for Redis)技术与应用解读》电子书你有没有想过这样一个问题:当下的互联网时代,网络覆盖了10.32亿人的生活,从衣食住行到日常社交,究竟是什么支撑着我们多样化的需求,它背后的底层系统到底是什么?是数据库。第一次听到这个答案可能会有点迟疑,细思一下,不无道理!随着短视频的兴起和支付系统的完善,越来越多人的物质消费、精神需求、情感导向等被算法一一俘获,“TA经济”在年轻人中迅速蔓延,人们也与数据库无数次不期而遇,比如:周末宅在家里,不想出门也不想做饭,饿了点外卖,查询附近的餐厅、附近的外卖商家,这些所有地理位置的查找,都需要数据库的存储;吃完饭躺在沙发上玩手机,微信朋友圈、微博、抖音以及头条等社交软件,系统及时且准确地推送着关注的好友或感兴趣的内容,这些Feed流信息的推送,也是数据库的功劳;到了晚上,各个直播间里“宝子们福利来喽,今天xx返场,全年最低价……”,这高亢的呼唤、迷人的价格让穿梭在直播间的看客们果断砍手,于是,账单来袭,不经意间又一次与数据库撞个满怀。数据库是存放数据的地方,它神秘但又无处不在,而类似于以上发生的场景,都有Redis忙碌的身影。提起Redis,互联网从业者里无人不知无人不晓。开源Redis作为一款经典的“缓存”产品,有着丰富的数据类型,不仅好用还支撑着众多业务的架构搭建,在游戏、电商、社交媒体及其他互联网领域有着重要地位。然而,在数据量和访问量指数级增长的今天,“容量有限,高并发写入容易OOM”、“内存昂贵、成本降不下来”、“可靠性有限,容易丢关键数据”的问题,也成了开源Redis绕不过的痛。不过,GaussDB(for Redis)完美地解决了开源Redis的难题。GaussDB(for Redis) 是华为云推出的一款,基于计算存储分离架构的云原生分布式数据库,兼容Redis生态的云原生NoSQL数据库,并提供强一致、三副本存储,高度保证数据的安全可靠。GaussDB(for Redis)突破了开源Redis的内存限制,通过将数据进行冷热分离,在保证热数据驻留计算节点内存满足业务低时延要求的同时,将冷数据置换入分布式存储池进行持久化存储,最大程度的降低使用成本,具有高兼容、高性价比、高可靠、弹性伸缩、高可用、冷热分离等特点。为了让开发者更加系统地了解GaussDB(for Redis),华为云数据库专家集经验与心血之所成,联合推出《GaussDB(for Redis)企业与技术解读》经典案例锦集,从入门篇、架构篇、测试篇、应用篇四个章节,全面解析GaussDB(for Redis)技术架构与实践,帮助开发者充分了解GaussDB(for Redis)的能力。附件可下载《GaussDB(for Redis)技术与应用解读》电子书
上滑加载中
推荐直播
-
0代码智能构建AI Agent——华为云AI原生应用引擎的架构与实践
2024/11/13 周三 16:30-18:00
苏秦 华为云aPaaS DTSE技术布道师
大模型及生成式AI对应用和软件产业带来了哪些影响?从企业场景及应用开发视角,面向AI原生应用需要什么样的工具及平台能力?企业要如何选好、用好、管好大模型,使能AI原生应用快速创新?本期直播,华为云aPaaS DTSE技术布道师苏秦将基于华为云自身实践出发,深入浅出地介绍华为云AI原生应用引擎,通过分钟级智能生成Agent应用的方式帮助企业完成从传统应用到智能应用的竞争力转型,使能千行万业智能应用创新。
去报名 -
TinyEngine低代码引擎系列第2讲——向下扎根,向上生长,TinyEngine灵活构建个性化低代码平台
2024/11/14 周四 16:00-18:00
王老师 华为云前端开发工程师,TinyEngine开源负责人
王老师将从TinyEngine 的灵活定制能力出发,带大家了解隐藏在低代码背后的潜在挑战及突破思路,通过实践及运用,帮助大家贴近面向未来低代码产品。
即将直播 -
华为云AI入门课:AI发展趋势与华为愿景
2024/11/18 周一 18:20-20:20
Alex 华为云学堂技术讲师
本期直播旨在帮助开发者熟悉理解AI技术概念,AI发展趋势,AI实用化前景,了解熟悉未来主要技术栈,当前发展瓶颈等行业化知识。帮助开发者在AI领域快速构建知识体系,构建职业竞争力。
即将直播
热门标签