• [热门活动] 数据库Codelabs咨询&问题&建议反馈帖
    尊敬的各位云数据库开发者    感谢大家对华为云数据库的关注与支持。    本帖为Codelabs咨询和问题反馈收集帖。大家在体验数据库Codelabs的过程中的任何问题和建议,均可以通过本帖进行反馈。我们会安排专人进行问题的收集与解答。请大家按照以下格式进行回帖:问题/咨询提交格式————————————————反馈类型(问题/咨询/建议):华为云账号:问题出现时间:问题/咨询/建议描述:截图:————————————————大家也可以移步华为云数据库Codelabs活动主帖,探索更多玩法,赢取精美礼品:<点我前往数据库Codelabs主贴>
  • [技术干货] 【云图说】第169期 华为云数据库 RDS for MySQL 小版本升级攻略
    新得一年,小云妹我又带着数据库的新知识来了,实例性能不断提升,升级必须安排上。云数据库 RDS for MySQL支持自动和手动升级内核小版本啦,详细操作,云图说为您详解~云数据库 RDS for MySQL介绍页入口:https://www.huaweicloud.com/product/mysql.html云数据库 RDS for MySQL成长地图入口:https://support.huaweicloud.com/rds/index.html【往期回顾】●【第一期】初始华为云关系型数据库RDS●【第二期】万万没想到,云数据库MySQL原来是这样的!●【第三期】这些购买云数据库MySQL的技能实用到哭,你确定不来看看?●【第四期】云数据库MySQL一键实现弹性扩展是种什么样的体验?●【第五期】太给力了!认识云数据库PostgreSQL只需要这三步●【第六期】这才是云数据库SQL Server正确的打开方式●【第七期】数据库的私人医生——云DBA●【第八期】小云妹带你快速玩转关系型数据库实例操作(一)●【第九期】小云妹带你快速玩转关系型数据库实例操作(二)
  • [技术干货] 扩容性能提升百倍!华为云GeminiDB的蓬勃张力
    在很长一段时间内,企业为了自身发展大多选择自建数据库,而随着企业的发展壮大和数据量的猛增,自建数据库越来越不能满足企业对数据库提出的高要求。为了更好地管理和使用海量数据,越来越多企业选择把云下数据库迁到云上,MongoDB数据库也在企业上云过程中展现出了蓬勃的发展张力。自建MongoDB VS 云上MongoDB服务可用自建MongoDB一般是自我深度优化后的产品,往往较原生性能有较大的提升,这也变相为用户提高了综合性价比。自建MongoDB针对原生产品功能不足,增强其功能,尤其是优先满足了一些企业特别需要的企业级功能,这也成为很多线下客户选择云数据库产品的重要考量因素。自建MongoDB的客户根据自己在某业务领域的积累,有针对性地增加了特定场景下的数据库端解决方案,有效提升了竞争力。云厂商立足根本,考验的是技术底蕴,需要企业长期投入并不断锤炼,还需要注重其兼容性,尽量减少对企业现状的冲击,并为其他有可能的选择做必要的铺垫。除此之外,监控、备份恢复、优化、容灾等服务能力对于企业的使用必不可少,如果没有云的话,这些能力往往需要企业花费大量精力去自建。云生态功能如果说上述功能企业还能容易具备,那么云功能则相对门槛过高了。云是指诸如弹性扩容/缩容等服务功能,这类能力往往需要依托强大的底座能力,需要较大的研发投入和长期积累才能具备。在某些特定场合下(如业务形态、幅度变化很大的企业客户)很具吸引力。企业选择上云,往往不仅仅依靠一两款产品,更多的是看中云端生态功能。对于企业来讲,如何通过云端打通技术瓶颈,快速具备业务能力成为核心。例如从数据埋点、数据捕捉、数据存储、数据计算到分析展示。如果全流程都可以在云端无缝集成,那么对于企业来说,无疑是一种很成功的服务体验。上云成本自建MongoDB在人力、财力、时间、风险等四个方面具有较大的成本。除了这些之外,我们也能经常听见客户的声音,如依赖过度、性能差、竞争力弱等,而随着上云进程的加快和各类基础云设施的完善,越来越多的企业把目光投向了云数据库。华为云GeminiDB for MongoDB接口的独特优势基于云时代下客户数据上云和企业的数字化转型,华为云数据库精心推出了一款产品—— GeminiDB。这是一款基于华为自主研发的计算存储分离架构的分布式多模NoSQL数据库服务,100%兼容MongoDB接口,并提供高性能、高可靠的优势和企业级服务。与自建MongoDB和市面上各类MongoDB云服务相比,GeminiDB for MongoDB接口构筑了以下优势:一是分钟级计算节点扩容和秒级存储扩容,扩容性能提升百倍,满足敏捷业务弹性需要。▸二是高性能,同等成本下提升了3倍读写性能。▸三是数据高可靠,基于分布式存储的数据副本故障快速恢复能力,副本重建时长缩短10倍+。此外,GeminiDB for MongoDB接口支持单套实例最大100TB数据,N-1个节点故障容忍,具备一键部署、监控报警等服务能力。华为云GeminiDB for MongoDB接口的应用实践MongoDB 的应用已经渗透到各个领域,比如游戏、物流、电商、内容管理、社交、物联网、视频直播等。华为云GeminiDB for MongoDB接口凭借过硬的技术优势和服务能力成功助力国家地理信息公共服务平台天地图,将44项在线业务全部迁移部署在华为云上,数据更新效率得到明显提升,原来需要15天才能完成的16TB全库数据恢复,现在2~3天就能完成;过去需要5小时才能完成的300GB数据迁移,现在1小时就能完成。此外,华为云GeminiDB for MongoDB接口还成功帮助锦江都城酒店PMS核心业务系统的迁移,PMS涉及渠道、支付、硬件、公安等接口的百项变更,对于连锁酒店而言是业内难度最高的迁移之一。而采用GeminiDB后,锦江都城的系统负载实现了3/4的降幅,能维持在20%左右,基本上不存在资源压⼒和系统稳定性⽅面的隐患。云数据库MongoDB的优势不言而喻,华为云数据库也会持之以恒地构筑GeminiDB for MongoDB接口的技术优势和服务能力,未来云数据库MongoDB的发展会越来越蓬勃,生命力也愈加强劲。目前,华为云数据库开年采购季活动火热进行中,在迁移专区购买数据库的用户, 使用数据复制服务DRS迁移数据上云后免费赠送6个月时长。
  • [热门活动] 【华为云数据库Codelabs】解锁云上数据库更多玩法,限量版礼品拿到手软
    错过了3月24日数据库大咖直播?不要紧~!我们为你准备了完整的录播!↓↓↓ 想了解数据库领域最新技术变革和实践应用的小伙伴看这里 ↓↓↓→   <点我观看完整录播>   ←如果对数据库产品有任何问题,也可以在这里反馈:<点我前往问题交流帖>我们会安排专人解答你的疑问HDC规则太复杂?现在带你玩转Codelabs,奖励拿到手软~小白如何体验Codelabs?小编悄悄告诉你,每个Codelab都有对应的专家指导视频哦~即刻前往云数据库线上展厅观看视频,然后体验Codelab,完成从小白到大神的蜕变~数据库Codelabs体验与视频链接                                      基于Python搭建云数据库应用        <点我体验Codelab>      <点我观看视频>                                      DAS数据追踪与回滚体验                <点我前往Codelab>      <点我观看视频>                                      GeminiDB性能比拼                       <点我前往Codelab>      <点我观看视频>                                      GeminiDB扩容比拼                       <点我前往Codelab>      <点我观看视频>                                      TaurusDB 性能比拼                       <点我前往Codelab>      <点我观看视频>                                      本地MySQL数据库在线迁移           <点我前往Codelab>       <点我观看视频>活动时间2020年3月23日-2020年3月28日参与方式点击上方体验链接,完成Codelabs体验流程,将完成结果截图即可参与评论数据库Codelabs互动交流贴各位开发者对于Codelabs有任何疑问或者建议,都可以移步交流帖与我们沟通哦!<点击前往>Codelabs汇总贴如果大家想了解其他Codelabs信息,也可以到汇总贴参观~ <点击前往>获奖信息填写指导请中奖的开发者按照《Codelabs互动活动中奖人收货信息填报操作指导》填写收货信息,我们将在活动结束后(3月28日)4月份为您陆续寄出礼品(所有礼品最终解释权归华为所有)<点击前往填报操作指导>                               福利一:参与体验Codelabs即可赢取码豆(码豆获取待定),兑换海量精美礼品:(HDC官网)                                        3月9日~3月25日期间,开发者可登陆免费领取100元代金券                          <点击领取>                                        3月23日~3月28日期间,开发者如需领取第二张代金券,可点击此链接申请   <点击申请>                                        四大主题活动,百万码豆等你来瓜分                                                              <点击前往>                               福利二:除了获得码豆兑换奖礼品,数据库还为大家额外准备了惊喜哦,具体玩法见下:                               玩法:请大家在体验数据库Codelabs完成后,将结果截图和体验感受回复在帖子中(截图中须体现用户名)                                         1、末尾为“9”的楼层,将会获得华为云云宝一个,仅限前200名。                                         2、评论+点赞数总和最多的前5个楼层,将会获得京东卡100元1张                                         3、同时我们也会挑选3名精彩回复(例如:谈谈自己对云数据库的理解、建议)送出神秘工程师大礼包                                         (包含:移动电源+运动发带+腰包或者背包+多功能数据线+旅行睡眠套装+户外小手电)                                         4、深度解析华文云数据库的文章,我们会邀请专家评选出3篇精彩文章,每人赠送价值500元的云数据                                              库代金券。                               特别提醒:                                         1、回帖字数必须大于等于15个字,并且附上有效的数据库Codelabs体验截图。                                         2、每个人至少完成一次有效的Codelab体验方可参与抽奖活动。                                         3、每个Codelab截图仅以第1次回帖为准(1个Codelab截图,多次回帖无效)。体验越多个数据库                                              Codelabs,中奖率越高!                                         4、体验过程中如果代金券余额不足,可点击链接免费申请第二张代金券。                                         奖池包括但不仅限于以下奖品哦~获奖名单公布请以上获奖者尽快发消息给版主“无关风月”核对收货地址,核对完成后奖品陆续发出,感谢大家的参与!获奖名单获得奖品KennyChan工程师大礼包、华为云云宝linzhuofeng工程师大礼包、华为云云宝追光者2020华为云云宝linjiachen华为云云宝chenzeshi华为云云宝以上奖品均已发出,请各位幸运开发者注意查收~如有疑问请私信版主“无关风月”
  • [技术干货] 还在担心数据删库操作?华为云数据库多重防护轻松解决
    最近有个删库跑路的帖子在网上引起热议,很多企业管理者都开始担忧数据库的安全可靠性。 其实是数据库安全和备份机制没做到位,如果一开始就采用严密的安全机制和完善的数据库备份机制,那么即便是误删了数据库也可以恢复如初。安全没到位再多功能体验也白搭数据安全是守护企业生命的一道有力防线,对企业未来发展至关重要。但绝大多数中小企业的自建数据库和一些云厂商的云数据库服务往往忽略了数据安全的重要性,自身安全防护机制不够严谨,容易面临各种网络攻击和企业内部高危操作的风险,尤其是对恶意删库这种致命性打击行为没有防护、追溯和恢复的能力。因此,我们应该更多思考的是如何保证数据不丢失,如何确保企业数据安全。那么,华为云提供了哪些安全机制,可以帮助企业避免这样的灾难性故障呢?保证数据高安全华为云数据库是这样做的华为云数据库通过VPC、子网、安全组、DDOS防护、数据加密、SSL加密传输、权限控制、回收站等多层安全防护体系,严格控制数据库实例的操作权限,详细记录数据库控制台操作和SQL执行日志,隔离对数据库的恶意访问,并在删库事件发生后具备保命的恢复逃生手段,可谓是三维一体、能够有效抵御网络攻击的防护措施。同时配合数据库安全服务DBSS提供的数据脱敏、数据库审计和防SQL注入攻击等功能,共同为企业数据安全保驾护航。针对删库这种降维打击,华为云数据库提供了多重防护措施:高权限管控华为云RDS配套使用的数据管理服务DAS即将推出企业版,DAS服务企业版对于删库、删表、truncate 这些永久性的物理删除操作,提供了严格的权限管控和控制,至少需要经过业务Owner/DBA/系统管理员三个角色完成审批才可以执行,同时支持通过增量日志解析删除语句,将被删除的数据行快速还原。细粒度权限控制针对删除实例这种高危操作,华为云数据库为企业用户研发了细粒度授权的特性,客户可针对用户和用户组配置细粒度权限策略,将删除数据库的权限控制在有限的高权限账号里面,防止用户的高危操作,保障数据的安全。华为云支持客户免费开启操作保护功能,删除实例的时候会强制执行6位验证码的二次验证,验证短信或邮件只发送给有限的几个手机号码或邮箱。自动备份恢复华为云数据库具备完善的备份恢复机制,732天超长保存,高度保证备份数据的可靠性。如果客户设置了自动备份策略,那么在备份保留周期内,如果只是删除了某些库表,可直接执行库表时间点恢复,将被删除的库表还原到删除前一刻,实现快速的表恢复。华为云RDS还有实例回收站特性,专门针对这种删库跑路的行为,即使包括备份文件在内的整个实例被删除了,在有限的周期内(可配置最长7天时间),也可以从回收站里找回。审计追踪华为云数据库不仅做到事前防护和事后还原,还可以追溯责任人,逐层找到问题根源。华为云RDS有SQL审计日志、支持查询/删除语句的执行用户名、请求来源IP、执行时间等;针对控制台的操作,华为云RDS还对接了云审计服务CTS,管控下发的删除实例的请求也会被审计到。总而言之,云数据库的安全除了依靠云服务商提供的保护能力,如危险操作双因子认证、数据库回收站等,还需要企业设立完整的企业数据库管理规范,严格控制各种角色对应的数据库权限,如权限的三权分立(即数据库管理员、数据库审计员、数据库安全员三权),从制度上预防任何可能的恶意行为。安全服务无小事,任何关及企业服务体验的事都是华为云数据库的头等大事。华为云数据库会持续构筑强硬的技术实力,提供更高安全、高可靠的数据库服务。目前,华为云数据库开年采购活动火热进行中,在迁移专区购买数据库的用户, 使用数据复制服务DRS迁移数据上云后免费赠送6个月时长。在活动页下单数据库的用户均免费赠送数据库安全审计1个月。此外新用户购买云数据库1年3折,2个月仅需10元。华为开发者大会2020(Cloud)是华为面向ICT(信息与通信)领域全球开发者的年度顶级旗舰活动。大会旨在搭建一个全球性的交流和实践平台,开放华为30年积累的ICT技术和能力,以“鲲鹏+昇腾”硬核双引擎,为开发者提供澎湃动力,改变世界,变不可能为可能。我们期待与你共创计算新时代在一起,梦飞扬!
  • [热门活动] 开年采购季|华为云数据库买1送6
    复工后想搞个大动作?这个“节流增效锦囊”必须了解一下华为云数据库开年采购季1 新用户空前优惠,云耀云服务器+云数据库爆款CP组合低至2折2 新用户6个月8折购赠送6个月,买1年55折赠送6个月,买3年只需5折赠送6个月3 新用户购买2个月仅需10元,个人开发者福音4 首次购买数据库的用户1年3折,优惠力度之大前所未有5 不限新老用户新购产品5折起,升级续订1年8折6 新品试用,GeminiDB for Cassandra 限时0元体验目前,华为云数据库开年采购活动火热进行中, 活动期间在活动页购买数据库产品(除文档数据库服务DDS以外)的用户,均免费赠送数据库安全审计服务1个月免费使用时长。买管家式的华为云数据库速戳:华为开发者大会2020(Cloud)是华为面向ICT(信息与通信)领域全球开发者的年度顶级旗舰活动。大会旨在搭建一个全球性的交流和实践平台,开放华为30年积累的ICT技术和能力,以“鲲鹏+昇腾”硬核双引擎,为开发者提供澎湃动力,改变世界,变不可能为可能。我们期待与你共创计算新时代在一起,梦飞扬!
  • GeminiDB for Cassandra 流功能介绍
    1      使用GeminiDB for Cassandra流捕获表活动1.1      功能介绍当存储在GeminiDB for Cassandra集群中某张表的某项目发生变更时,其他的程序能够做出相应的变更,比如:一个应用程序更改了GeminiDB for Cassandra集群中的某行数据,另一个应用程序能够读取到这行数据变更并做出相应的动作。GeminiDB for Cassandra支持这种类似的场景。流表捕获原表的变动,并存储24小时之后过期。客户端通过SDK可访问流表并获取数据修改前后的项目数据。GeminiDB for Cassandra流是一种有关表中的项目修改的有序信息流,当启动某张表的流时,GeminiDB for Cassandra流表捕获原表的数据项目的更改信息。当应用程序在表中插入、更新、或者删除某条数据时,流表都会记录一条修改数据的流记录。流记录包含对表中某条数据所做的数据修改的相关信息,包含修改前后的新旧数据记录。原表中修改的每个项目,流表中的记录将按照对应的实际修改的顺序显示。流表会实时的监控原表的记录,包括插入、删除、更新操作,以便能够在其他情况使用,但不包含DDL操作记录;流表使用GeminiDB for Cassandra的物化视图实现,遵循物化视图的相关限制,比如有必须先删除物化视图表之后才能删除原表,对应必须要先删除流表才能删除原表。1.2      使用场景主要用于Cassandra往大数据/ES(Elasticsearch)同步数据变化的场景,支撑客户对应业务开展。1.3      功能特色华为GeminiDB for Cassandra专有能力,原生Cassandra不支持。2      GeminiDB for Cassandra流使用方法概述GeminiDB for Cassandra原表与流表维护两个独立的表。在开启原表的流开关之后,访问原表并且有操作原表数据会记录到对应的流表中,要读取处理流表记录,通过访问流表,访问方式与数据库其他表的访问方式相同,见第四、五章节访问方法。3      开启关闭流启用流的方式:使用alter table KS.TABLE with stream_enabled=true 语句启用流,当前流支持新旧映像。关闭流:使用alter table KS.TABLE with stream_enabled=false 可以随时禁用流。关闭流之后当前流表中的数据不会立即删除,24之后删除,原表中数据的变更不会再记录到流表中。举例:CREATE TABLE ks.table   ( id int, name text, addr text,age int,email text,PRIMARY KEY (name, id));     // 创建表Alter TABLE ks.table   with stream_enabled=true;     // 开启流Desc ks.table;     // 查看流表是否创建INSERT INTO ks.table   (name , id , addr , age , email ) VALUES ('xiaoxin',31,'beijing1',33,'xiaoxin@163.com');   // 向原表写入数据select * from ks."table$streaming";   // 查看流表是否有相应数据产生Alter TABLE ks.table   with stream_enabled=false;   // 关闭流表 4      读取和处理流记录应用程序要读取和处理流时,应用程序需要通过SDK连接到C*流表进行相应操作。流表中的每条流记录均代表一个原表中数据的修改,每条流记录都会有一个时间信息,标识这条流产生的时间信息。每条流记录会在24小时后自动删除。流表结构:CREATE TABLE ks.table$streaming (       @shardID   text,       @eventID   timeuuid,       pk,       ck,       @newOldImage   boolean,      @eventName text,       co1,       co2,         PRIMARY   KEY (@shardID, @eventID, pk, ck, @newOldImage)  //pk,ck,为原表的pk,ck, co1,co2是原表的普通列);如上,流表中包含几个特殊的字段:"@shardID"是分区键;"@eventID"是由插入时间生成的timeuuid,代表流数据产生的时间;"@newOldImage"代表新旧映像,0表示旧映像,1表示新映像;"@eventName"代表操作事件如"insert"、"update"、"delete"。迭代处理流表的数据时请使用流表的分区加上时间戳范围访问。查询分区时使用,返回分区列表:select stream_shards from   system_schema.tables  where   keyspace_name='ks' and table_name='table';例如:cqlsh:ks> select stream_shards from system_schema.tables  where keyspace_name='ks' and   table_name='table1';  stream_shards-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ['-9223372036854775808',   '-6148914691236517206', '-4611686018427387905', '-3843071682022823258',   '-1537228672809129303', '-2', '1537228672809129299', '4611686018427387901',   '5270498306774157603', '6148914691236517202', '7686143364045646492',   '7686143364045646503'] (1 rows)使用分区+时间遍历流表数据,范围查询时使用"@eventID"时间查询,每次默认返回的大小根据数据量大小决定,下次迭代使用时间继续往后迭代。例如:select * From ks."table$streaming"   where "@shardID" = '-9223372036854775808' and "@eventID"   > a64a8340-e999-11e9-a7bd-cb5f001f61df limit 50;select * From ks."table$streaming"   where "@shardID" in ('-9223372036854775808', '-6148914691236517206', '-4611686018427387905', '-3843071682022823258', '-1537228672809129303', '-2', '1537228672809129299', '4611686018427387901', '5270498306774157603', '6148914691236517202', '7686143364045646492', '7686143364045646503')  limit 50;5      接口说明5.1      GetShardIteratorpublic static List<String>   GetShardIterator(Cluster cluster, String keySpace, String tableName)功能: 获取流表的shard信息入参:Cluster cluster:集群的cluster信息,连接数据库使用String keySpace:要查询流数据的数据库名称String tableName:要查询流数据的表名称出参:       返回List<String> 一组shard集合,GetRecords接口中使用5.2      GetRecordspublic static StreamInfo   GetRecords(Cluster cluster, String keySpace, TableEvent tableEvent)功能: 获取流表的具体数据入参:Cluster cluster:集群的cluster信息,连接数据库使用String keySpace:要查询流数据的数据库名称TableEvent tableEvent:要查询流数据相关信息,TableEvent结构如下:       String table:要查询流数据的表名称String shardID:要查询流数据的shardIDString eventID:要查询流数据的时间戳信息int limitRow:要查询流数据的限制条数,没有指定情况下默认是100;出参:返回一组StreamInfo数据;具体结构如下:       String shardID:流数据的shardIDString table:流数据的原表名List<RowInfo> columns:一组流数据的集合,RowInfo具体结构如下:String eventID:流数据的时间戳信息String operateType:操作类型,例如: INSERT、UPDATE、DELETEList<DataItem> Keys: 流数据对应的原表的主键信息List<DataItem> NewImage: 新映像的信息List<DataItem> OldImage: 旧映像的信息5.3      GetShardIteratorpublic static List<String>   GetShardIterator(Session session, String keySpace, String tableName)功能: 获取流表的shard信息入参:Session session:数据库集群的连接session,调用函数之后session需要调用者关闭String keySpace:要查询流数据的数据库名称String tableName:要查询流数据的表名称出参:       返回List<String> 一组shard集合,GetRecords接口中使用5.4      GetRecordspublic static StreamInfo GetRecords(Session   session, String keySpace, TableEvent tableEvent)功能: 获取流表的具体数据入参:Session session:数据库集群的连接session,调用函数之后session需要调用者关闭;String keySpace:要查询流数据的数据库名称;TableEvent tableEvent:要查询流数据相关信息,TableEvent结构如下:       String table:要查询流数据的表名称;String shardID:要查询流数据的shardID;String eventID:要查询流数据的时间戳信息;int limitRow:要查询流数据的限制条数,没有指定情况下默认是100;List<ColumnMetadata> primaryKey: 要查询流数据的表的主键名称类型信息出参:返回一组StreamInfo数据;具体结构如下:       String shardID:流数据的shardIDString table:流数据的原表名List<RowInfo> columns:一组流数据的集合,RowInfo具体结构如下:String eventID:流数据的时间戳信息String operateType:操作类型,例如: INSERT、UPDATE、DELETEList<DataItem> Keys: 流数据对应的原表的主键信息List<DataItem> NewImage: 新映像的信息List<DataItem> OldImage: 旧映像的信息5.5      GetRecords返回结果范例{       "ShardID":   "-4611686018427387905",       "Table":   "tb1",       "Records":   [{              "EventID":   "52236080-efb5-11e9-9c62-49626763b3dc",              "OperateType":   "INSERT",              "Keys":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   31,                     "type":   "int"              }],              "NewImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   31,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }],              "OldImage":   []       },   {              "EventID":   "52255c50-efb5-11e9-9c62-49626763b3dc",              "OperateType":   "UPDATE",              "Keys":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   32,                     "type":   "int"              }],              "NewImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   32,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }],              "OldImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   32,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }]       },   {              "EventID":   "52261fa0-efb5-11e9-9c62-49626763b3dc",              "OperateType":   "UPDATE",              "Keys":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   33,                     "type":   "int"              }],              "NewImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }],              "OldImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value": 33,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }]       }]} 5.6      接口使用demo1package com.huawei.hwcloud.stream;       import com.datastax.driver.core.Cluster;   import com.datastax.driver.core.ColumnMetadata;   import com.google.gson.Gson;   import com.google.gson.GsonBuilder;   import com.huawei.hwcloud.stream.req.RowInfo;   import com.huawei.hwcloud.stream.req.StreamInfo;   import com.huawei.hwcloud.stream.req.TableEvent;     import java.util.List;       public class Main {       public static void main(String[] args) {           Cluster cluster = Cluster.builder().addContactPoint("xxx.95.xxx.201").withPort(9042).build();   //        Cluster cluster = Cluster.builder().addContactPoint(endpoint).withPort(port).withCredentials(username, password).build();           List<ColumnMetadata> pm = cluster.getMetadata().getKeyspace("test").getTable("tb1").getPrimaryKey();         System.out.println(pm);         List streamShards = null;         try {             streamShards = StreamFetcher.GetShardIterator(cluster, "test", "tb1");         }         catch (Exception e) {             e.printStackTrace();         }         System.out.println(streamShards);           TableEvent tableEvent = new TableEvent();         tableEvent.setEventID("43e0eeb0-ee80-11e9-9c62-49626763b3dc");         tableEvent.setShardID("-4611686018427387905");         tableEvent.setTable("tb1");         tableEvent.setLimitRow(6);           StreamInfo streamInfo = null;         try {             streamInfo = StreamFetcher.GetRecords(cluster, "test", tableEvent);         }         catch (Exception e) {             e.printStackTrace();         }           Gson gson = new GsonBuilder().create();         String line = gson.toJson(streamInfo);         System.out.println(line);           System.out.println(streamInfo.getColumns().size());         for (RowInfo rowInfo: streamInfo.getColumns()) {             System.out.println(rowInfo.toString());         }           System.exit(0);     } }   5.7      接口使用demo2package com.huawei.hwcloud.stream;       import com.datastax.driver.core.Cluster;   import com.datastax.driver.core.ColumnMetadata;   import com.datastax.driver.core.Session;   import com.google.gson.Gson;   import com.google.gson.GsonBuilder;   import com.huawei.hwcloud.stream.req.RowInfo;   import com.huawei.hwcloud.stream.req.StreamInfo;   import com.huawei.hwcloud.stream.req.TableEvent;   import com.huawei.hwcloud.stream.utils.WrapperCassandraSession;     import java.util.List;     public class Main2 {       public static void main(String[] args) {           Cluster cluster = Cluster.builder().addContactPoint("XXX.95.XXX.201").withPort(9042).build();   //        Cluster cluster = Cluster.builder().addContactPoint(endpoint).withPort(port).withCredentials(username, password).build();           List<ColumnMetadata> pk = cluster.getMetadata().getKeyspace("test").getTable("tb1").getPrimaryKey();         System.out.println(pk);           Session session = cluster.connect();         List<String> streamShards = StreamFetcher.GetShardIterator(session, "test", "tb1");         System.out.println(streamShards);             TableEvent tableEvent = new TableEvent();         tableEvent.setEventID("43e0eeb0-ee80-11e9-9c62-49626763b3dc");         tableEvent.setShardID("-4611686018427387905");         tableEvent.setTable("tb1");         tableEvent.setLimitRow(6);         tableEvent.setPrimaryKey(pk);           StreamInfo streamInfo = StreamFetcher.GetRecords(session, "test", tableEvent);           Gson gson = new GsonBuilder().create();         String line = gson.toJson(streamInfo);         System.out.println(line);           System.out.println(streamInfo.getColumns().size());         for (RowInfo rowInfo: streamInfo.getColumns()) {             System.out.println(rowInfo.toString());         }           session.close();           System.exit(0);     } }   6      功能约束流表中的数据保留24小时。流表中的数据会占用数据库的磁盘空间。通过CQL语句不能创建带有"$streaming"后缀的流表。流表可以通过drop MATERIALIZED VIEW ks."table$streaming";进行删除,流表使用物化视图实现,遵从物化视图的限制要求。    
  • GeminiDB for Cassandra 流功能介绍
    1      使用GeminiDB for Cassandra流捕获表活动1.1      功能介绍当存储在GeminiDB for Cassandra集群中某张表的某项目发生变更时,其他的程序能够做出相应的变更,比如:一个应用程序更改了GeminiDB for Cassandra集群中的某行数据,另一个应用程序能够读取到这行数据变更并做出相应的动作。GeminiDB for Cassandra支持这种类似的场景。流表捕获原表的变动,并存储24小时之后过期。客户端通过SDK可访问流表并获取数据修改前后的项目数据。GeminiDB for Cassandra流是一种有关表中的项目修改的有序信息流,当启动某张表的流时,GeminiDB for Cassandra流表捕获原表的数据项目的更改信息。当应用程序在表中插入、更新、或者删除某条数据时,流表都会记录一条修改数据的流记录。流记录包含对表中某条数据所做的数据修改的相关信息,包含修改前后的新旧数据记录。原表中修改的每个项目,流表中的记录将按照对应的实际修改的顺序显示。流表会实时的监控原表的记录,包括插入、删除、更新操作,以便能够在其他情况使用,但不包含DDL操作记录;流表使用GeminiDB for Cassandra的物化视图实现,遵循物化视图的相关限制,比如有必须先删除物化视图表之后才能删除原表,对应必须要先删除流表才能删除原表。1.2      使用场景主要用于Cassandra往大数据平台/ES(Elasticsearch)同步数据变化的场景,支撑客户对应业务开展。1.3      功能特色华为GeminiDB for Cassandra专有能力,原生Cassandra不支持。2      GeminiDB for Cassandra流使用方法概述GeminiDB for Cassandra原表与流表维护两个独立的表。在开启原表的流开关之后,访问原表并且有操作原表数据会记录到对应的流表中,要读取处理流表记录,通过访问流表,访问方式与数据库其他表的访问方式相同,见第四、五章节访问方法。3      开启关闭流启用流的方式:使用alter table KS.TABLE with stream_enabled=true 语句启用流,当前流支持新旧映像。关闭流:使用alter table KS.TABLE with stream_enabled=false 可以随时禁用流。关闭流之后当前流表中的数据不会立即删除,24之后删除,原表中数据的变更不会再记录到流表中。举例:CREATE TABLE ks.table   ( id int, name text, addr text,age int,email text,PRIMARY KEY (name, id));     // 创建表Alter TABLE ks.table   with stream_enabled=true;     // 开启流Desc ks.table;     // 查看流表是否创建INSERT INTO ks.table   (name , id , addr , age , email ) VALUES ('xiaoxin',31,'beijing1',33,'xiaoxin@163.com');   // 向原表写入数据select * from ks."table$streaming";   // 查看流表是否有相应数据产生Alter TABLE ks.table   with stream_enabled=false;   // 关闭流表 4      读取和处理流记录应用程序要读取和处理流时,应用程序需要通过SDK连接到C*流表进行相应操作。流表中的每条流记录均代表一个原表中数据的修改,每条流记录都会有一个时间信息,标识这条流产生的时间信息。每条流记录会在24小时后自动删除。流表结构:CREATE TABLE ks.table$streaming (       @shardID   text,       @eventID   timeuuid,       pk,       ck,       @newOldImage   boolean,      @eventName text,       co1,       co2,         PRIMARY   KEY (@shardID, @eventID, pk, ck, @newOldImage)  //pk,ck,为原表的pk,ck, co1,co2是原表的普通列);如上,流表中包含几个特殊的字段:"@shardID"是分区键;"@eventID"是由插入时间生成的timeuuid,代表流数据产生的时间;"@newOldImage"代表新旧映像,0表示旧映像,1表示新映像;"@eventName"代表操作事件如"insert"、"update"、"delete"。迭代处理流表的数据时请使用流表的分区加上时间戳范围访问。查询分区时使用,返回分区列表:select stream_shards from   system_schema.tables  where   keyspace_name='ks' and table_name='table';例如:cqlsh:ks> select stream_shards from system_schema.tables  where keyspace_name='ks' and   table_name='table1';  stream_shards-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ['-9223372036854775808',   '-6148914691236517206', '-4611686018427387905', '-3843071682022823258',   '-1537228672809129303', '-2', '1537228672809129299', '4611686018427387901',   '5270498306774157603', '6148914691236517202', '7686143364045646492',   '7686143364045646503'] (1 rows)使用分区+时间遍历流表数据,范围查询时使用"@eventID"时间查询,每次默认返回的大小根据数据量大小决定,下次迭代使用时间继续往后迭代。例如:select * From ks."table$streaming"   where "@shardID" = '-9223372036854775808' and "@eventID"   > a64a8340-e999-11e9-a7bd-cb5f001f61df limit 50;5      接口说明5.1      GetShardIteratorpublic static List<String>   GetShardIterator(Cluster cluster, String keySpace, String tableName)功能: 获取流表的shard信息入参:Cluster cluster:集群的cluster信息,连接数据库使用String keySpace:要查询流数据的数据库名称String tableName:要查询流数据的表名称出参:       返回List<String> 一组shard集合,GetRecords接口中使用5.2      GetRecordspublic static StreamInfo   GetRecords(Cluster cluster, String keySpace, TableEvent tableEvent)功能: 获取流表的具体数据入参:Cluster cluster:集群的cluster信息,连接数据库使用String keySpace:要查询流数据的数据库名称TableEvent tableEvent:要查询流数据相关信息,TableEvent结构如下:       String table:要查询流数据的表名称String shardID:要查询流数据的shardIDString eventID:要查询流数据的时间戳信息int limitRow:要查询流数据的限制条数,没有指定情况下默认是100;出参:返回一组StreamInfo数据;具体结构如下:       String shardID:流数据的shardIDString table:流数据的原表名List<RowInfo> columns:一组流数据的集合,RowInfo具体结构如下:String eventID:流数据的时间戳信息String operateType:操作类型,例如: INSERT、UPDATE、DELETEList<DataItem> Keys: 流数据对应的原表的主键信息List<DataItem> NewImage: 新映像的信息List<DataItem> OldImage: 旧映像的信息5.3      GetShardIteratorpublic static List<String>   GetShardIterator(Session session, String keySpace, String tableName)功能: 获取流表的shard信息入参:Session session:数据库集群的连接session,调用函数之后session需要调用者关闭String keySpace:要查询流数据的数据库名称String tableName:要查询流数据的表名称出参:       返回List<String> 一组shard集合,GetRecords接口中使用5.4      GetRecordspublic static StreamInfo GetRecords(Session   session, String keySpace, TableEvent tableEvent)功能: 获取流表的具体数据入参:Session session:数据库集群的连接session,调用函数之后session需要调用者关闭;String keySpace:要查询流数据的数据库名称;TableEvent tableEvent:要查询流数据相关信息,TableEvent结构如下:       String table:要查询流数据的表名称;String shardID:要查询流数据的shardID;String eventID:要查询流数据的时间戳信息;int limitRow:要查询流数据的限制条数,没有指定情况下默认是100;List<ColumnMetadata> primaryKey: 要查询流数据的表的主键名称类型信息出参:返回一组StreamInfo数据;具体结构如下:       String shardID:流数据的shardIDString table:流数据的原表名List<RowInfo> columns:一组流数据的集合,RowInfo具体结构如下:String eventID:流数据的时间戳信息String operateType:操作类型,例如: INSERT、UPDATE、DELETEList<DataItem> Keys: 流数据对应的原表的主键信息List<DataItem> NewImage: 新映像的信息List<DataItem> OldImage: 旧映像的信息5.5      GetRecords返回结果范例{       "ShardID":   "-4611686018427387905",       "Table":   "tb1",       "Records":   [{              "EventID":   "52236080-efb5-11e9-9c62-49626763b3dc",              "OperateType":   "INSERT",              "Keys":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   31,                     "type":   "int"              }],              "NewImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   31,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }],              "OldImage":   []       },   {              "EventID":   "52255c50-efb5-11e9-9c62-49626763b3dc",              "OperateType":   "UPDATE",              "Keys":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   32,                     "type":   "int"              }],              "NewImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   32,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }],              "OldImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   32,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }]       },   {              "EventID":   "52261fa0-efb5-11e9-9c62-49626763b3dc",              "OperateType":   "UPDATE",              "Keys":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   33,                     "type":   "int"              }],              "NewImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }],              "OldImage":   [{                     "columnName":   "name",                     "value":   "zhoujielun",                     "type":   "varchar"              },   {                     "columnName":   "id",                     "value": 33,                     "type":   "int"              },   {                     "columnName":   "addr",                     "value":   "宇宙中心",                     "type":   "varchar"              },   {                     "columnName":   "age",                     "value":   33,                     "type":   "int"              },   {                     "columnName":   "email",                     "value":   "zhoujielun.com",                     "type":   "varchar"              }]       }]} 5.6      接口使用demo1package com.huawei.hwcloud.stream;       import com.datastax.driver.core.Cluster;   import com.datastax.driver.core.ColumnMetadata;   import com.google.gson.Gson;   import com.google.gson.GsonBuilder;   import com.huawei.hwcloud.stream.req.RowInfo;   import com.huawei.hwcloud.stream.req.StreamInfo;   import com.huawei.hwcloud.stream.req.TableEvent;     import java.util.List;       public class Main {       public static void main(String[] args) {           Cluster cluster = Cluster.builder().addContactPoint("xxx.95.xxx.201").withPort(9042).build();   //        Cluster cluster = Cluster.builder().addContactPoint(endpoint).withPort(port).withCredentials(username, password).build();           List<ColumnMetadata> pm = cluster.getMetadata().getKeyspace("test").getTable("tb1").getPrimaryKey();         System.out.println(pm);         List streamShards = null;         try {             streamShards = StreamFetcher.GetShardIterator(cluster, "test", "tb1");         }         catch (Exception e) {             e.printStackTrace();         }         System.out.println(streamShards);           TableEvent tableEvent = new TableEvent();         tableEvent.setEventID("43e0eeb0-ee80-11e9-9c62-49626763b3dc");         tableEvent.setShardID("-4611686018427387905");         tableEvent.setTable("tb1");         tableEvent.setLimitRow(6);           StreamInfo streamInfo = null;         try {             streamInfo = StreamFetcher.GetRecords(cluster, "test", tableEvent);         }         catch (Exception e) {             e.printStackTrace();         }           Gson gson = new GsonBuilder().create();         String line = gson.toJson(streamInfo);         System.out.println(line);           System.out.println(streamInfo.getColumns().size());         for (RowInfo rowInfo: streamInfo.getColumns()) {             System.out.println(rowInfo.toString());         }           System.exit(0);     } }   5.7      接口使用demo2package com.huawei.hwcloud.stream;       import com.datastax.driver.core.Cluster;   import com.datastax.driver.core.ColumnMetadata;   import com.datastax.driver.core.Session;   import com.google.gson.Gson;   import com.google.gson.GsonBuilder;   import com.huawei.hwcloud.stream.req.RowInfo;   import com.huawei.hwcloud.stream.req.StreamInfo;   import com.huawei.hwcloud.stream.req.TableEvent;   import com.huawei.hwcloud.stream.utils.WrapperCassandraSession;     import java.util.List;     public class Main2 {       public static void main(String[] args) {           Cluster cluster = Cluster.builder().addContactPoint("XXX.95.XXX.201").withPort(9042).build();   //        Cluster cluster = Cluster.builder().addContactPoint(endpoint).withPort(port).withCredentials(username, password).build();           List<ColumnMetadata> pk = cluster.getMetadata().getKeyspace("test").getTable("tb1").getPrimaryKey();         System.out.println(pk);           Session session = cluster.connect();         List<String> streamShards = StreamFetcher.GetShardIterator(session, "test", "tb1");         System.out.println(streamShards);             TableEvent tableEvent = new TableEvent();         tableEvent.setEventID("43e0eeb0-ee80-11e9-9c62-49626763b3dc");         tableEvent.setShardID("-4611686018427387905");         tableEvent.setTable("tb1");         tableEvent.setLimitRow(6);         tableEvent.setPrimaryKey(pk);           StreamInfo streamInfo = StreamFetcher.GetRecords(session, "test", tableEvent);           Gson gson = new GsonBuilder().create();         String line = gson.toJson(streamInfo);         System.out.println(line);           System.out.println(streamInfo.getColumns().size());         for (RowInfo rowInfo: streamInfo.getColumns()) {             System.out.println(rowInfo.toString());         }           session.close();           System.exit(0);     } }   6      功能约束流表中的数据保留24小时。流表中的数据会占用数据库的磁盘空间。通过CQL语句不能创建带有"$streaming"后缀的流表。流表可以通过drop MATERIALIZED VIEW ks."table$streaming";进行删除,流表使用物化视图实现,遵从物化视图的限制要求。    
  • [技术干货] 【云图说】第166期 华为云自研云数据库GaussDB NoSQL 兼容多款NoSQL接口的数据库服务
    本期小云妹给大家介绍个数据库的新成员——云数据库GaussDB NoSQL云数据库GaussDB(for Cassandra)介绍页入口:https://www.huaweicloud.com/product/gaussdbforcassandra.html云数据库GaussDB(for Mongo) 介绍页入口:https://www.huaweicloud.com/product/gaussdbformongo.html云数据库GaussDB NoSQL成长地图入口:https://support.huaweicloud.com/nosql/index.html
  • [技术干货] 还在担心事务丢失?华为云数据库MySQL帮您轻松解决
    随着数据上云进程的加快,越来越多企业愿意把云下数据库搬到云上,同时对云上数据库的要求也越来越高。尤其是数据的完整可靠,承载着企业业务持续发展的使命,其重要性不言而喻。而企业在云上使用过程中,事务经常面临丢失的风险,可靠性和完整性得不到满足,很大程度上影响了企业的业务发展。针对这个问题,华为云数据库MySQL高可靠的应用机制能够保证事务不丢失,进而保证企业业务的稳定发展。部分云厂商为了保证事务不丢失,而选择增加一个数据库结点的方式,从而成本也上升了。华为云数据库MySQL高可靠特性介绍华为云数据库MySQL 高可靠特性是华为云数据库团队精心推出的重大功能特性,基于主备模式下在最大程度保证主库效率的同时,保证主库崩溃时快速恢复服务,并且做到事务零丢失,进而保证企业业务的稳定持续。主备模式是现今RDS  for MySQL最为流行的部署形态,通常采用半同步复制。华为云数据库MySQL半同步复制凭借高可靠特性能够精准判断主库崩溃时的复制状态,并根据主库崩溃时的复制状态自行准确恢复服务,很好地保障了数据的高可靠性。华为云数据库MySQL保证数据高可靠的秘诀精准判断主库崩溃时的复制状态 华为云数据库MySQL半同步复制基于状态通道和时间戳的高可靠特性,总体上是管控节点(HA)保存主库最后的复制状态和时间戳,备实例保存主库最后的复制状态和时间戳,然后通过比较它们来精准判断主库崩溃时的复制状态。根据主库崩溃状态自行恢复服务 华为云数据库MySQL半同步复制状态下绝大多数情况是同步复制状态,极少数情况下(如执行大事务时)会转换到异步复制状态,然后自动转换回同步复制状态。而现在华为云数据库半同步复制凭借高可靠特性能够精准判断主库崩溃时的复制状态,并根据主库崩溃时的复制状态按照以下四种情况准确恢复服务:在同步复制状态下主库崩溃,拉起主库,保证不丢失事务,并且秒级恢复服务。l   在同步复制状态下主库崩溃,如果不能拉起主库,服务平滑切换到备库,保证不丢失事务,并且秒级恢复服务。l   在异步复制状态下主库崩溃,不能切换到备库,拉起主库,保证不丢失事务,并且秒级恢复服务。l   在异步复制状态下主库崩溃后,不能切换到备库,如果不能拉起主库,会在原来的数据上恢复主库,保证不丢失事务,并且分钟级恢复服务。华为云数据库MySQL半同步复制高可靠特性能最大程度保证主库效率,是因为主库的事务提交只依赖于备库,而备库把这个事务写入中继日志后立即返回一个ACK(即确认字符),没有强同步复制备库回放事务带来的延迟。场景应用机房掉电 当用户购买了华为云数据库MySQL,其主库所在的机房掉电,主库挂掉,用户服务被中断时,华为云数据库MySQL凭借高可靠特性可以使服务在秒级内平滑切换到备库,用户可以重新连接上华为云数据库,并且做到服务与中断前的数据视图完全一致,没有任何事务丢失。执行大事务时数据库挂掉 当用户购买的华为云数据库MySQL半同步复制主库正在执行大事务,并且复制状态从同步复制转换到异步复制时,主库突然挂掉,用户服务被迫中断,华为云数据库MySQL主库会在秒级内被拉起对外提供服务,用户可以重新连接上华为云数据库,并且与中断前的数据视图完全一致,没有事务丢失。华为云数据库MySQL半同步复制高可靠特性不仅能够保证事务不丢失, 而且能够保证秒级恢复服务(极端情况下,分钟级恢复服务),从而确保主备数据的一致性,保障企业数据的高可靠,为企业发展保驾护航,同时也是践行华为云数据库致力于打造企业级数据和最强数据底座的有力体现。
  • [技术干货] 云原生数据库三驾马车之TaurusDB
    【前言】Taurus是华为对标AWS Aurora的一款重磅云原生数据库。其设计思想是Log-as-database以最小化网络IO,采用计算存储分离的架构。Taurus的市场定位是OLTP的企业级市场以及高端MySQL客户,但兼顾中小客户。技术路线上兼容MySQL/PG生态,减少客户获取成本,降低风险。本文介绍Taurus数据库产品产生的背景、系统架构以及技术细节。此外,我们还对比了AWS Aurora/Aliyun PolarDB与Taurus的一些特性。相关背景             图1. 第一代云数据库系统架构    在移动互联和物联网等新的应用场景之下,半结构化与非结构化数据例如图片、文本、音频、视频等出现爆炸性增长。传统数据库系统难以应对大数据时代下的存储需求,企业客户迫切需要新的数据库产品,具备动态扩缩容、高吞吐量、低成本等。在云计算技术不断成熟的背景之下,云数据库开始崛起,并因为按需扩展、按需付费等优异特性获得中小企业及互联网客户的青睐。云数据库经历了若干时期的发展,逐渐从托管式服务进化到云原生数据库。云原生数据库在某种程度上颠覆了传统数据库的架构设计。因为云环境基本已经提供相应的高可用功能,而大部分云厂商提供的数据库服务并没有利用这个特性从而错过许多优化空间。以MySQL为例子,如图1所示,数据库系统部署在虚拟机和分布式块存储之上。每个数据库有一个主实例和至少一个只读实例。外部客户通过一个虚拟IP(VIP)访问数据库。当主节点发生故障,云端管理软件会将VIP自动切换至新的主实例。主实例和只读实例都将数据存放在云存储的块设备上。主实例将数据页、保证页面原子性的double write以及redo日志通过文件系统接口写入云存储侧,然后将binlog发送到只读节点。只读节点接收到这些binlog之后写入relaylog,然后回放日志重建数据库副本。回放线程也会将这个过程产生的redo日志,binlog和数据页写到云存储。整个系统可以工作,但是却存在如下几个问题。l  存储空间浪费为了确保数据的可靠性,云存储对于写入的数据一般都是采用3副本存储。所有的数据库实例包括主实例和只读实例都是将数据写入云存储。这种情况下,主实例是3副本存储,其它只读实例也是3副本存储,总共消耗3*(N+1)副本的存储空间,其中N为只读实例的个数。理想情况下,整个数据库系统只需为主实例保留一份数据,只读实例可以共享这份数据,那么可以极大地节省存储空间。l  较大的RTO和数据滞后在现有的RDS部署中,数据库系统的高可用取决于主备之间binlog同步和故障切换协议。在事务提交之前,主机将binlog同步至备机,等待备机的ACK。备机将接收到的binlog进行回放,重建数据库副本。主机发生故障的时候,备机只有将binlog回放完成才能接管系统,对外提供服务。在云环境,MySQL将数据存储在远端的分布式云存储上。数据库日常操作产生的磁盘IO都会转化成网络IO。对比本地存储,云存储的优点在于提供了更大以及更可靠的存储空间。它的主要不足在于延迟较大。这直接影响了备机binlog回放性能。虽然MySQL5.6支持MTS特性,但是一个库只有一个回放线程。在最坏的情况下,需要等待数小时备机才能就绪,对外提供服务。MySQL5.7引入MTS多线程并行回放特性,但是帮助有限,这仍然不能从根本上解决问题。本质上而言,主库的更新压力越大,从库回放日志的时间也就越长,接管系统等待的时长随之增加。因此系统的RTO增大。由于从库需要回放日志来反映主库上的更新,备机回放性能的不足使得主从延迟较大。理想的情况下是,主备共享云端的数据,这可以完全消除备机回放过程和开销,极大地缩小RTO和主从滞后。l  计算资源浪费在现有的RDS部署中,创建备机的主要目的是回放binlog,备机不响应任何的客户端请求。这其中主要的原因是防止查询工作负载影响回放进程。类似地,只读副本系统的回放进程也会影响查询性能。如果备机能够消除回放过程,那么系统的所有计算都可以用来相应用户请求。l  系统性能RDS MySQL主实例将redo日志、binlong和数据页(双写)写入远端的分布式云存储。当系统redo存储空间或缓冲区脏页比例达到阈值,MySQ进行checkpoint操作将脏页写入云存储。对比本地存储,云端较大的写时延制约系统的性能,特别是写入性能。在AWS Aurora纯写测试基准下,现有MySQL RDS的QPS是50~60K,而Aurora能够到达110k。在64个虚拟处理核心下,Aurora甚至能够达到200K的QPS。l  网络带宽消耗在当前的RDS部署中,所有数据库实例都会通过网络将其所有数据写入后端云存储。以master为例,一个MySQL master实例需要写redo日志、binlog和数据页(双写)。对于Aurora纯写测试基准,峰值吞吐量为200 K QPS,这转换为70 M字节/秒的重做日志,但是,写数据页将生成另外700 M字节/秒的流量。对于云存储,所有这些都是多副本存储。这仅对于单个数据库实例。在这种带宽消耗规模下,在相同基础架构上运行的数据库实例数量将会很少。此外还有写入放大、大库支撑不足和从库加入时间较长等问题。Amazon首先意识到上述问题,近年来推出的云数据库Aurora就是为云计算时代而专门定制的一款关系型数据库。其目标主要是最小化网络IO,充分利用云基础设施来提升系统的可扩展性与可用性。Aurora的设计哲学是log is database,对数据的更改只写日志,不刷脏页,极大地简化恢复子系统。Amazon宣称Aurora的RTO最大为2分钟左右;可以在秒级时间内完成故障节点切换与扩容,性能对比MySQL5.6可以优10倍。TaurusDB作为一款cloud native的数据库,设计理念类似AWS Aurora,但青出于蓝而更胜于蓝。TaurusDB不仅针对IO与写操作进行了优化,而且还考虑了读优化,让应用程序可以在缓冲区内以最小的代价获得最新的数据,明显区别于国内厂商(腾讯CynosDB基本完全按照AWS Aurora的设计思路,与TaurusDB原型版本设计思路类似,这里我们把它归为AWS Aurora一类)。TaurusDB针对用户痛点进行了相应的技术革新,对比第一代云数据库其优点相当明显。以下是TaurusDB的架构设计,文章的最后是TaurusDB与其它厂商的对比。                                                                                                             TaurusDB特点             图2. 基于DFV共享存储的TaurusDB架构TaurusDB是华为MySQL RDS经历了云盘时代单机版、Active-Standby主备版和金融高可用一主两备三节点架构版本后,作为华为云自研的最新一代cloud native分布式数据库。它采用华为下一代云存储(DFV)实现弹性扩缩容、高可用和共享存储。如图2所示,系统自顶向下分为3大部分,SQL节点、存储抽象层SAL(Storage Abstract Layer)以及存储节点(storage server)。TaurusDB SQL节点形成一个集群,包括一个主节点和多个只读副本(RO,最多15个)。每个集群属于一个云租户,一个租户可以具有多个集群。SQL节点管理客户端连接,解析SQL请求,生成查询执行计划,执行查询以及管理事务隔离。主节点和只读副本之间的通信流量很小,主要交换一些状态信息(DDL更新、slice/pages分配更新和活跃事务列表、只读副本中最旧的读取视图、副本最小LSN)。在故障切换期间,任何只读副本都可以接管集群。只有主SQL节点负责数据库更新和DDL操作,而只读副本处理数据库只读查询,并为客户端提供可重复读(RR)和读已提交(RC)隔离级别。如图2所示,SAL(存储抽象层)是SQL节点和存储层之间的桥接器。SAL包括两个主要组件,SAL SQL模块和DFV存储节点内部的Slice存储。SAL SQL模块为SQL节点(主/只读副本)提供了SAL API,用以与底层存储系统进行交互。如图3所示, SAL SQL模块包含通用日志处理器CLP(Common Log Processor)、数据库分片管理器SM(Slice Manager)、页面读取器PR(Page Reader)以及与只读副本节点同步信息的工具程序。CLP负责将数据库全局重做日志持久到DFV,解析日志并将其分发到相应的DFV分片,并生成同步消息(脏页,活动事务列表,分片持久LSN等)以供只读副本获取。CLP还需要处理数据库崩溃恢复,重新加载已提交的全局重做日志并将其重新分配给所有相应的分片。SM维护分片策略以及页面映射信息,确定何时添加更多的分片以及哪些数据库页面应分配给哪个DFV切片等。页面读取器负责通过查找页面映射信息将特定的页面读取请求路由到相应的切片管理器。SAL SQL模块还为SQL节点与存储系统交互提供了其他一些接口,包括定期将日志清除信息(RecycleLSN)传递到数据库片等。                          图3. SAL-SQL包含的主要模块Slice Store是在DFV存储节点内部运行的插件模块。它需要与DFV存储框架一起使用,用以在相同DFV节点上管理多个数据库片,支持多租户资源共享,并将页面的多个版本提供给SQL节点。如图4所示,对于每个分片,slice Store使用日志目录作为中心组件来管理重做日志和页面数据。Slice store的主要职责是1) 接收分片重做日志,将其持久化并注册到日志目录中;2)接收页面阅读请求并构建特定版本的页面;3)垃圾回收和合并日志。                                                图4.slice store组件TaurusDB存储层建立在华为云存储DFV持久层之上。DFV持久层为上层SQL节点存储提供读写接口,提供跨地域3AZs之间的数据强一致性和可靠性保证。 TaurusDB使用两种模式实现write-optimized以及read-optimized,分别是PLOG模式与iShard模式。PLOG模式提供强一致性保证,而iShard模式实现最终的一致性。TaurusDB SQL节点使用PLOG模式存储整个数据库的WAL重做日志,使用iShard模式对数据在多个存储节点之间进行分片和管理。PLOG以SSD友好的追加写方式使事务提交更快;iShard将redo以页面为单位进行聚合,管理数据分片,实现快速数据读取,并支持超大型数据库(128 TB)。存储层支持多个TaurusDB集群实例,单个存储节点支持多租户数据库分片。部署灵活,可以将PLOG和iShard部署在单独的存储池中或共享同一存储池。在这种体系架构下,整个数据库集群只需一份足够可靠的数据库副本集,极大地节约成本。所有只读副本共享在云存储中的数据,去除数据库层的复制逻辑。一写多读,没有独立的备用实例。主节点发生故障,集群进行切换操作时,只读副本都可以切换为主节点,接管集群服务。为了节省宝贵的网络带宽,只有数据库日志通过网络从数据库计算节点写入 DFV 存储层,没有脏页、逻辑日志和双写的流量。基于 DFV 存储层内的数据库日志重构数据面,独立于上层的计算节点,实现存储和计算分离。为了应对大数据存储需求,TaurusDB利用DFV的切片策略对数据库进行自动分区,对应用透明。单个DFV存储节点可以管理来自不同数据库集群实例的多个分片,实现存储容量无限扩展。TaurusDB的设计中,充分使用了异步线程、批量IO以及流水线工作模式实现写入高性能。这对于有大量写入需求的场景,例如物联网是相当合适的。通过在存储层内嵌数据库插件可以快速读取所需的数据。从这一角度上来说,TaurusDB是一个write-optimized以及read-optimized的数据库系统。总的来说,TaurusDB具有以下的优点:1.   节省资源如上所述,TaurusDB只需一份足够可靠的数据库副本集。所有只读副本共享云存储中的数据。添加只读节点时,只需添加计算节点,无需额外购买存储。只读节点越多,节省的存储成本越多。另外一个值得注意的地方就是数据库去除了复制逻辑,对比主备高可用架构这在一定程度上了节省了网络流量,提升计算节点效率。总体而言,在成本开销上,TaurusDB提供企业级的服务能力,但只有1/10商用数据库的成本。2.   便捷扩展性与高可靠性在第一代云数据库的主从架构下,添加只读时需要拷贝数据,重放 binlog,这要求备库完整地执行一次查询请求,在大数据量情况下速度很慢,尤其是对于采用本地盘方案。主从复制延迟问题会影响主备切换,无法保证 RTO,影响SLA。此外,备份恢复速度很慢,TB级的数据量通常需要耗费数小时,使得数据库扩展性严重受限。对比传统的逻辑复制,物理复制则没有上述缺点。因为物理复制只需在日志指定的存储位置上恢复/应用数据的前置镜像/后置镜像即可,完全跳过了查询执行过程。TaurusDB采用物理复制,减少IO操作的同时,让复制更加可靠、高效,并且几乎不会对性能造成影响。由此带来秒级主备切换、快速动态的读扩展和故障恢复。TaurusDB最高支持扩展到15个只读节点。虽然TaurusDB使用了物理复制,但是基于客户在数据分析和传输上需要Binlog,我们也支持Binlog进行数据同步。得益于底层强一致分布式文件系统DFV的支撑以及TaurusDB架构在数据访问上的设计,TaurusDB支持跨AZ部署,跨region容灾,实现单点故障0中断,满足金融级别可靠性。3.   高性能TaurusDB包含MySQL 8.0的所有重要功能,还在其基础之上进行了大量的优化,例如针对硬件特性的适配与大并发下的优化。TaurusDB对封锁子系统进行了分区,减少了锁表的竞争,并行化死锁检测;在事务子系统上采用Lock-Free数据结构来管理事务子系统的活跃事务列表。除此之外,引入内核特性,例如Query result cache,Query plan cache,Online DDL等提升用户体验。相比于TaurusDB1.0版本,TaurusDB2.0版本在性能表现上有了显著提升,在关键情况下都有了数倍的改进。对比MySQL 8.0的官方版本,TaurusDB2.0的优化改进所带来的效果也非常明显,尤其是物理复制方面具有显著的优势。在纯写情况下,TaurusDB2.0的性能可以比官方MySQL8.0高7倍以上。4.   强悍的备份恢复支撑TaurusDB 引擎采用定制的新一代分布式存储系统DFV,极大提升了数据备份、恢复性能。DFV持久层集群包括多个存储节点。每个存储节点包含多个SSD设备和适应SSD介质的append存储服务进程,提供AppendOnly vs. WriteInPlace的数据写入模式。DFV将数据按多时间点多副本存储,支持海量快照和快照秒级生成。在这种能力支撑之下,基于底层存储系统的多时间点模式,TaurusDB不需增量日志回放,可直接实现按时间点回滚,轻松支持PITR(Point-In-Time-Recovery)特性。TaurusDB将特定计算任务(备份与恢复逻辑)下推到DFV,以便更高效,快速地实现备份、恢复,而上层计算节点专注于业务逻辑处理。在这种模式之下,客户可以通过本地访问数据并直接与第三方存储系统交互,高并发高性能。通过异步数据拷贝外加按需实时数据加载机制, TaurusDB 可在数分钟内达到完整功能可用,实现快速实例恢复。横向比较      TaurusDB 的共享存储架构将数据持久化放入新一代存储中,充分保障数据强一致性和 0 丢失;针对硬件定制上层系统,充分利用 RDMA 网络、NVME SSD 等硬件优势,在这些关键技术上整合创新,使得 TaurusDB 的性能有了质的飞跃。对比目前业界的同类型产品,AWS Aurora和阿里的PoloarDB,TaurusDB的纯写性能方面要优30%左右。从阿里云对外公布的技术资料分析,PolarDB仍然需要将数据页写入存储侧,对数据进行SSD不友好的update-in-place操作。相比Aurora,PolarDB在体系结构上进行了一些创新,例如与数据库交互的IO设计、与现代硬件的适配等。腾讯的CynosDB则基本上参照AWS的Aurora进行设计,也沿用了很多系统概念例如数据段一致LSN(SCL),MTR完全点(CPL),最大存储卷MTR完全点(VDL)等。TaurusDB为了应用程序能够在计算节点以最小代价读到最新的数据,另辟蹊径对系统架构进行了不同层面的思考。利用CLP组件实现快速事务提交,利用slice store达到读优化的目的。在这点上,TaurusDB跟SAP HANA的设计思路有类似之处,数据在系统不同阶段有不同的作用。SAP HANA中,数据从行存储形态逐渐转化成列存储,从写优化向读优化演变;而TaurusDB中,日志从开始阶段的写优化通过compact操作向读优化演进。日志兼顾保证系统的持久性与效率。在不同的时期,日志的作用不同。系统恢复阶段,日志通过回放将系统恢复到最新一致性状态;在系统正常运行阶段,日志通过回放将系统最新数据提供给应用程序。并且得益于对多版本数据的剪枝(页面解析plug-in),计算节点可以以最小的代价从存储节点获得最新数据,无需RDMA网络的支撑即可高效完成。这也是TaurusDB能够顺利实现跨AZ部署,跨region容灾的关键点。表一是从用户较关心的角度出发,对TaurusDB,AWS Aurora以及阿里PolarDB“三驾马车”的横向对比。文章的最后,欢迎对taurus感兴趣的技术人员加入我们一起挑战技术巅峰,长风破浪,直挂云帆济沧海!简历发送至zhuyuean@huawei.com                                                    表一 TaurusDB VS. PolarDB VS.Aurora RPO (PITR)RTO       MySQL/PG兼容          系统纯写性能比率    支持跨AZ 只写logTaurusDBY <=30sec               Y                    1 Y      Y阿里PolarDBY >=1min               Y                   0.7 N      NAWS AuroraY <=30sec               Y                   0.7 Y      Y
  • [技术干货] 华为云数据库携手WeLink保障企业云上办公数据稳定可靠
    这个春节因为肺炎疫情的严峻,很多企业都实行了“在家办公”的工作模式,如何让在家办公变得安全轻松?华为云数据库携手WeLink(远程协作办公软件)共同保障企业在云上办公的数据稳定可靠,助力企业高效轻松办公。华为云WeLink智能工作平台提供IM、会议、办公等三大服务,春节期间新增企业数数十万,新增日活用户数超100万,业务流量增长50倍,单个企业最大会议方数760方,参会人员遍布国内230个城市。办公变得更轻松高效。华为云数据库具备便携安全的迁移和高级运维能力,疫情期间特别推出了免费专区活动,那么,华为云数据库是如何助力企业云上办公的呢?高稳定:支持TB级数据,轻松应对海量访问云上办公面临海量企业和用户同时涌入和远程办公的挑战,对网络要求较高,如何让企业稳定持续办公是每个远程协作办公软件必须思考的问题,而华为云WeLink借助华为云数据库MySQL的高稳定性,轻松解决了这个问题。华为云MySQL采用高可用主备架构,支持跨可用区部署主备实例,主备秒级自动切换,提供更低的RTO保证。同时支持在线扩展只读负载和存储容量扩容,一键规格变更实现CPU内存扩容和缩容,在高并发的大量连接下,提供更快速的响应,有效助力华为云WeLink提供百万级高并发和TB级数据,轻松应对访问压力。高可靠:数据一键备份恢复,支持跨AZ部署数据可靠是企业极为关注的问题,也是华为云WeLink十分重视的问题。WeLink服务使用华为云数据库MySQL作为核心数据库,数据基于云盘三副本保存,提供了极高的数据可靠性,无需担心硬件损坏导致数据丢失,华为云数据库MySQL自研的增强半同步协议,在保证主备高可用的同时确保数据不丢不漏,成功助力华为云WeLink IM服务(如群聊、即时消息等)的高可靠,让用户的沟通更及时高效。同时华为云文档数据库服务DDS采用副本集和分片集群两种高可用架构,数据自动备份,支持跨AZ部署,容灾能力强,具备一键恢复功能,有效防范误操作,在华为云WeLink 小微助手和投票系统中都发挥了重要作用。高安全:多层防护体系为数据安全保驾护航云上数据安全防护一样不能少,华为云WeLink凭借华为云数据库的高安全性,切实保障企业客户数据的安全。华为云数据库通过工信部可信云认证,采用安全组、VPC、DDOS防护以及SSL安全访问等多层技术严格控制访问,具备安全事后审计功能,可有效抵御网络攻击,配合数据库安全服务DBSS提供敏感数据发现、数据脱敏、数据库审计和防注入攻击等功能,共同为企业数据安全保驾护航。华为云数据库提供高稳定、高可靠、高安全的云上数据库服务,全力支撑华为云WeLink云上办公的高效便捷,致力为广大企业用户提供一个安全、开放、智能的办公服务平台数据底座,有效保障企业云上办公的数据稳定可靠,使您在家MySQL与DDS免费试用2个月,更多活动详情请戳:https://activity.huaweicloud.com/free_test/index.html华为开发者大会2020(Cloud)是华为面向ICT(信息与通信)领域全球开发者的年度顶级旗舰活动。大会旨在搭建一个全球性的交流和实践平台,开放华为30年积累的ICT技术和能力,以“鲲鹏+昇腾”硬核双引擎,为开发者提供澎湃动力,改变世界,变不可能为可能。我们期待与你共创计算新时代在一起,梦飞扬!
  • 第二届华为云数据库挑战赛-商业组作品参考方案
    点击文末附件下载PPT原件
  • [热门活动] 云数据库新年狂欢
    年关将至,云数据库新年狂欢火热来袭,新用户仅需10元即可畅享爆款云数据库,首购专享1年低至3折,新年新购1年75折,3年45折,包年购买数据库产品即免费赠送数据库安全服务DBSS一个月使用时长。还可免费体验新品GeminiDB for Cassandra,优惠多多,惊喜连连,快来寻找属于你的云数据库专“鼠”优惠吧!
  • [数据库] 【第4课】一键开通云数据库 MySQL读写分离功能,轻松应对业务高峰期
    华为云数据库MySQL提供一键开通读写分离功能,只需要一个连接地址,让您在业务高峰期不再迷茫,不再慌乱,轻松应对业务需求。什么是读写分离?读写分离是指通过一个读写分离的连接地址实现读写请求的自动转发。通过RDS的读写分离连接地址,写请求自动访问主实例,读请求按照读权重设置自动访问各个只读实例。什么时候使用读写分离?在对数据库有少量写请求,但有大量读请求的应用场景下,单个实例可能无法抵抗读取压力,甚至对主业务产生影响。为了实现读取能力的弹性扩展,分担数据库压力,您可以在某个区域中创建一个或多个只读实例,利用只读实例满足大量的数据库读取需求,以此增加应用的吞吐量。开通读写分离功能注意: 您拥有主备实例4U8G以上,1个只读实例即可开通读写分离功能。1.   登录管理控制台。2.   单击管理控制台左上角的,选择区域和项目。3.   选择“数据库 > 云数据库 RDS”。进入云数据库 RDS信息页面。4.   在实例列表中,单击目标实例的名称,进入实例的“基本信息”页面。5.   在左侧导航栏中,单击“读写分离”。您还可以在实例的“基本信息”页面,单击“连接信息”模块“读写分离地址”后的“申请”,跳转到“读写分离”页面。通过读写分离地址,可以快速实现读写分离访问,简单、高效、便携。如何设置阈值和权重开通读写分离功能后,您可以根据需要设置读写分离的延迟阈值和读权重分配。延时阈值只读实例同步主实例数据时允许的最长延迟时间。为避免只读实例读取的数据长时间和主实例不一致,当一个只读实例的延迟时间超过设置的延迟阈值,则不论该只读实例的读权重是多少,读请求都不会转发至该只读实例。读写分离功能成功开启后,延时阈值默认为30s,阈值默认范围为0~7200s,建议该阈值不小于30s,超出阈值的只读实例不分配流量。读权重分配读写分离功能成功开启后,主实例的读权重默认为0,可以修改;只读实例可以设置读权重。实例的读权重越高,处理的读请求越多。例如,假设主实例有4个只读实例,实例的读权重分别为0、100、200、500、300,则表示主实例不处理读请求(写请求仍然自动发往主实例),四个只读实例按照1:2:5:3的比例处理读请求。开通读写分离功能后,系统将根据只读实例的规格默认分配权重,后续新增只读实例也将按照默认规则分配权重。华为云数据库一键开通读写分离功能后,还可以快速弹性扩展,几分钟便可以完成只读实例的添加,且最多可以增加10个只读实例。轻松应对各类业务场景,助力企业服务创新升级。了解更多,请戳我...