华为云用户手册

  • 操作步骤 连接DDM实例。 连接方法具体请参考连接DDM实例。 打开dml_test_1逻辑库。 use dml_test_1; 输入命令创建全局序列。 create sequence seq_test; 使用以下语句,实现全局序列在insert语句或者replace语句的使用。 insert into test_seq(col1,col2)values(seq_test.nextval,seq_test.currval); 打开dml_test_2逻辑库。 use dml_test_2; 使用以下语句,实现全局序列在insert语句或者replace语句的使用。 insert into test_seq(col1,col2)values(dml_test_1.seq_test.nextval,dml_test_1.seq_test.currval); 由于全局序列是创建在逻辑库“dml_test_1”下的,在逻辑库“dml_test_2”下使用全局序列需要显式指定逻辑库“dml_test_1.seq_test.nextval”、“dml_test_1.seq_test.currval”。 全局序列结合insert和replace的使用只支持拆分表,不支持广播表和单表。 nextval和currval在insert和replace语句中是从左到右执行的,如果一条语句使用同一个全局序列nextval多次,每出现一次就递增一次。 全局序列是属于逻辑库的,删除逻辑库,所在删除逻辑库的全局序列也会被删除。
  • 操作步骤 登录分布式数据库中间件控制台。 在“参数模板”页面的“自定义”页签,选择一个用户创建的参数模板,单击“比较”。 您也可以在“参数模板”页面的“系统默认”页签,选择一个用户创建的参数模板进行比较。 选择不同参数模板,单击“确定”,比较两个参数模板之间的配置参数差异项。 图1 选择并比较参数模板 有差异项,则会显示差异参数模板的如下信息:参数名称、两个参数模板的参数值。 无差异项,则不显示。 图2 对比参数模板
  • 检查当前逻辑库下所有逻辑表各分表的DDL一致性 用途:用于对某逻辑库所有的逻辑表的一致性情况进行全局概览。 命令格式: check table 命令输出: 如果全部逻辑表都一致, 输出结果为: 如果存在不一致的逻辑表, 输出结果为: 输出详解: 每一行表示一个逻辑表的检查结果概况。 DATABASE_NAME:逻辑库名称。 TABLE_NAME:逻辑表名称。 TABLE_TYPE:逻辑表类型。 SINGLE:单表。 BROADCAST:广播表。 SHARDING:拆分表。 DDL_CONSISTENCY:该逻辑表对应所有物理表DDL是否一致。 TOTAL_COUNT:该逻辑表有几个物理表。 INCONSISTENT_COUNT:该逻辑表有几个物理表的DDL不一致。 DETAILS:DDL不一致的物理表名。 父主题: CHECK TABLE
  • 语法限制 不支持INSERT DELAYED...。 不支持不包含拆分字段的INSERT。 暂不支持PARTITION 语法,建议不要使用partition表。 INSERT操作不支持datetime(YYYY-MM-DD HH:MM:SS)中“YYYY”取值1582年及之前年份。 INSERT操作不支持插入拆分键值为DEFAULT关键字。 拆分表执行INSERT操作时如果指定了自增值,只影响该插入数据的自增值。后续数据插入时如果不指定自增值,仍以原自增值为基础进行自增。 不支持在VALUES中调用REPEAT函数时引用表中的列作为参数。 例如: INSERT INTO T(NAME) VALUES(REPEAT(ID,3)); 使用INSERT DUPLICATE...更新拆分键时仅支持常量,不支持VALUES、LAST_INSERT_ID等函数或运算表达式。 不支持INSERT DUPLICATE语句更新含GSI的拆分表。
  • 常用语法 INSERT [INTO] tbl_name [(col_name,...)] {VALUES | VALUE} ({expr },...),(...),... [ ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... ] OR INSERT [INTO] tbl_name SET col_name={expr | DEFAULT}, ... [ ON DUPLICATE KEY UPDATE col_name=expr [, col_name=expr] ... ]
  • 操作步骤 连接DDM实例。 连接方法具体请参考连接DDM实例。 连接成功后,打开目标逻辑库。 输入命令创建全局序列。 create sequence seq_test; 输入命令,返回下一个序列值。 select seq_test.nextval; 输入命令,获取当前序列值。 select seq_test.currval; 输入命令,批量获取序列值。 select seq_test.nextval(n); 批量获取序列值场景不支持跨库操作。 未使用过全局序列时,currval的返回值是0。
  • 不同实例类型的副本和分片数 单机实例:单机实例只有1个节点,1个Redis进程,当Redis进程故障后,DCS为实例重新拉起一个新的Redis进程。 主备/读写分离实例:分片数为1,包含一个主节点,一个或多个备节点。当主节点出现故障时,会进行主备倒换,恢复业务。副本数(备节点)越多,保障性更强,对实例的性能没有影响。 集群实例:集群实例由多个分片组成,每个分片默认是一个双副本的主备实例。例如一个3分片,3副本的集群实例,则每个分片都有3个节点(1个主节点,2个备节点)。 实例类型 分片数 副本数 负载均衡 占用IP数 单机 单分片 单副本,不支持多副本 - 1个 主备 单分片 默认双副本 Redis 4.0/5.0版本主备实例支持2-10副本,其他版本仅支持2副本 不支持 占用IP个数=副本数 读写分离 单分片 默认双副本,支持2-6副本 支持 1个 Proxy集群 多分片 双副本,不支持其他副本数 支持 1个 Cluster集群 多分片 默认双副本 Redis 4.0/5.0版本Cluster集群支持1-5副本,Redis 6.0版本支持1-2副本 不支持 占用IP个数=副本数*分片数
  • 数据设计规范 分类 原则 原则说明 级别 备注 Key相关规范 使用统一的命名规范。 一般使用业务名(或数据库名)为前缀,用冒号分隔。Key的名称保证语义清晰。 建议 例如,业务名:子业务名:id 控制Key名称的长度。 在保证语义清晰的情况下,尽量减少Key的长度。有些常用单词可使用缩写,例如,user缩写为u,messages缩写为msg。 建议 建议不要超过128字节(越短越好)。 禁止包含特殊字符(大括号“{}”除外)。 禁止包含特殊字符,如空格、换行、单双引号以及其他转义字符。 强烈建议 由于大括号“{}”为Redis的hash tag语义,如果使用的是集群实例,Key名称需要正确地使用大括号避免分片不均的情况。 Value相关规范 设计合理的Value大小。 设计合理的Key中Value的大小,推荐小于10 KB。 建议 过大的Value会引发分片不均、热点Key、实例流量或CPU使用率冲高等问题,还可能导致变更规格和迁移失败。应从设计源头上避免此类问题带来的影响。 设计合理的Key中元素的数量。 对于集合和列表类的数据结构(例如Hash,Set,List等),避免其中包含过多元素,建议单Key中的元素不要超过5000个。 建议 由于某些命令(例如HGETALL)的时间复杂度直接与Key中的元素数量相关。如果频繁执行时间复杂度为O(N)及以上的命令,且Key中的子Key数量过多容易引发慢请求、分片流量不均或热点Key问题。 选择合适的数据类型。 合理地选择数据结构能够节省内存和带宽。 建议 例如存储用户的信息,可用使用多个key,使用set u:1:name "X"、set u:1:age 20存储,也可以使用hash数据结构,存储成1个key,设置用户属性时使用hmset一次设置多个,同时这样存储也能节省内存。 设置合理的过期时间。 合理设置Key的过期时间,将过期时间打散,避免大量Key在同一时间点过期。 建议 设置过期时间时,可以在基础值上增减一个随机偏移值,避免在同一个时间点大量Key过期。大量Key过期会导致CPU使用率冲高。
  • 运维管理规范 原则 原则说明 级别 备注 生产开启密码保护 生产系统中需要开启Redis密码保护机制。 强烈建议 - 现网操作安全 禁止开发人员私自连到线上Redis服务。 强烈建议 - 验证业务的故障处理能力或容灾逻辑 在测试环境或者预生产环境中组织演练,验证在Redis主备倒换、宕机或者扩缩容场景下业务的可靠性。 建议 主备倒换可以自行在页面上触发。强烈建议使用Lettuce客户端的应用进行相关的演练。 监控实践 关注Redis负载,在过载前提前扩容。 强制 根据告警基线配置告警:配置节点cpu、内存、带宽等告警。 日常巡检 例行检查各个节点的内存使用率,查看主节点内存使用率是否有不均衡的状态。 建议 内存使用率不均衡说明存在大Key问题,需要进行大Key拆分及优化。 开启热Key例行分析,并分析是否有Key频繁调用。 建议 - 例行诊断Redis实例的命令,分析O(N)类命令是否存在隐患。 建议 针对O(N)命令,即使耗时很小,建议开发分析业务增长,N是否会增长。 例行巡检Redis慢日志命令。 建议 针对慢日志分析隐患,并尽快从业务上进行修复。
  • 命令使用规范 原则 原则说明 级别 备注 谨慎使用O(N)复杂度的命令 时间复杂度为O(N)的命令,需要特别注意N的值。避免N过大,造成Redis阻塞以及CPU使用率冲高。 强烈建议 例如:hgetall、lrange、smembers、zrange、sinter这些命令都是做全集操作,如果元素很多,会消耗大量CPU资源。可使用hscan、sscan、zscan这些分批扫描的命令替代。 禁用高危命令 禁止使用flushall、keys、hgetall等命令,或对命令进行重命名限制使用。 强烈建议 请参考命令重命名的内容。 慎重使用select Redis多数据库支持较弱,多业务用多数据库实际还是单线程处理,会有干扰。最好是拆分使用多个Redis。 建议 - 使用批量操作提高效率 如果有批量操作,可使用mget、mset或pipeline,提高效率,但要注意控制一次批量操作的元素个数。 建议 mget、mset和pipeline的区别如下: mget和mset是原子操作,pipeline是非原子操作。 pipeline可以打包不同的命令,mget和mset做不到。 使用pipeline,需要客户端和服务端同时支持。 避免在lua脚本中使用耗时代码 lua脚本的执行超时时间为5秒钟,建议不要在lua脚本中使用比较耗时的代码。 强烈建议 比如长时间的sleep、大的循环等语句。 避免在lua脚本中使用随机函数 调用lua脚本时,建议不要使用随机函数去指定key,否则在主备节点上执行结果不一致,从而导致主备节点数据不一致。 强烈建议 - 遵循集群实例使用lua的限制 遵循集群实例使用lua的限制。 强烈建议 使用EVAL和EVALSHA命令时,命令参数中必须带有至少1个key,否则客户端会提示“ERR eval/evalsha numkeys must be bigger than zero in redis cluster mode”的错误。 使用EVAL和EVALSHA命令时,DCS Redis集群实例使用第一个key来计算slot,用户代码需要保证操作的key是在同一个slot。 对mget,hmget等批量命令做并行和异步IO优化 某些客户端对于MGET,HMGET这些命令没有做特殊处理,串行执行再合并返回,效率较低,建议做并行优化。 建议 例如Jedis对于MGET命令在集群中执行的场景就没有特殊优化,串行执行,比起lettuce中并行pipeline,异步IO的实现,性能差距可达到数十倍,该场景建议使用Jedis的客户端自行实现slot分组和pipeline的功能。 禁止使用del命令直接删除大Key 使用del命令直接删除大Key(主要是集合类型)会导致节点阻塞,影响后续请求 强烈建议 Redis 4.0后的版本可以通过UNLINK命令安全地删除大Key,该命令是异步非阻塞的。 对于Redis 4.0之前的版本: 如果是Hash类型的大Key,推荐使用hscan + hdel 如果是List类型的大Key,推荐使用ltrim 如果是Set类型的大Key,推荐使用sscan + srem 如果是SortedSet类型的大Key,推荐使用zscan + zrem
  • SDK使用规范 原则 原则说明 级别 备注 使用连接池和长连接 短连接性能差,推荐使用带有连接池的客户端。 建议 连接的频繁创建和销毁,会浪费大量的系统资源,极限情况会造成宿主机宕机。请确保使用了正确的Redis客户端连接池配置。 客户端需要对可能的故障和慢请求做容错处理 由于Redis服务可能因网络波动或基础设置故障的影响,引发主备倒换,命令超时或慢请求等现象,需要在客户端内设计合理的容错重试机制。 建议 参考Redis客户端重试指南。 合理设置重试时间和次数 合理设置容错处理的重试时间,根据业务要求设置,避免过短或者过长。 强烈建议 如果超时重试时间设置的非常短(例如200毫秒以下),可能引发重试风暴,极易引发业务层雪崩。 如果重试时间设置得较长或者重试次数设置得较大,则可能导致在主备倒换情况下业务恢复较慢。 避免使用Lettuce客户端 Lettuce客户端在默认配置下有一定性能优势,并且是spring的默认客户端,但是Jedis客户端在面对连接异常,网络抖动等场景下的异常处理和检测能力明显强于Lettuce,可靠性更强,建议使用Jedis。 建议 Lettuce存在几个方面的问题: Lettuce默认未配置集群拓补刷新的配置,会导致Cluster集群在发生拓补信息变化(主备倒换,扩容缩容)时,无法识别新的节点信息,导致业务失败。可参考使用Lettuce连接Cluster集群实例时的扩容异常处理。 Lettuce没有连接池校验的功能,无法检测连接池中的连接是否仍然有效,获取失效连接之后会导致业务失败。
  • 业务使用规范 原则 原则说明 级别 备注 就近部署业务,避免时延过大 如果部署位置过远(非同一个region)或者时延较大(例如业务服务器与Redis实例通过公网连接),网络延迟将极大影响读写性能。 强烈建议 如果对于时延较为敏感,请避免创建跨AZ Redis实例。 冷热数据区分 建议将热数据加载到 Redis 中。低频数据可存储在 Mysql或者ElasticSearch中。 建议 Redis将低频数据存入内存中,并不会加速访问,且占用Redis空间。 业务数据分离 避免多个业务共用一个Redis。 强烈建议 一方面避免业务相互影响,另一方面避免单实例膨胀,并能在故障时降低影响面,快速恢复。 禁止使用select功能在单Redis实例做多db区分。 强烈建议 Redis单实例内多DB隔离性较差,Redis开源社区已经不再发展多DB特性,后续不建议依赖该特性。 设置合理的内存淘汰(逐出)策略 合理设置淘汰策略,可以在Redis内存意外写满的时候,仍然正常提供服务。 强烈建议 DCS默认的逐出策略为volatile-lru,请根据业务需求选择。Redis支持的数据逐出策略 以缓存方式使用Redis Redis事务功能较弱,不建议过多使用。 建议 事务执行完后,不可回滚。 数据异常的情况下,支持清空缓存进行数据恢复。 强烈建议 Redis本身没有保障数据强一致的机制和协议,业务不能强依赖Redis数据的准确性。 以缓存方式使用Redis时,所有的key需设置过期时间,不可把Redis作为数据库使用。 强烈建议 失效时间并非越长越好,需要根据业务性质进行设置。 防止缓存击穿 推荐搭配本地缓存使用Redis,对于热点数据建立本地缓存。本地缓存数据使用异步方式进行刷新。 建议 - 防止缓存穿透 非关键路径透传数据库,建议对访问数据库进行限流。 建议 - 从Redis获取数据未命中时,访问只读数据库实例。可通过域名等方式对接多个只读实例。 建议 核心是未命中的缓存数据不会打到主库上。 用域名对接多个只读数据库实例,一旦出现问题,可以增加只读实例应急。 不用作消息队列 发布订阅场景下,不建议作为消息队列使用。 强烈建议 如没有非常特殊的需求,不建议将 Redis 当作消息队列使用。 Redis 当作消息队列使用,会有容量、网络、效率、功能方面的多种问题。 如需要消息队列,可使用高吞吐的Kafka或者高可靠的RocketMQ。 合理选择规格 如果业务增长会带来Redis请求增长,请选择集群实例(Proxy集群和Cluster集群) 强烈建议 单机和主备扩容只能实现内存、带宽的扩容,无法实现计算性能扩容。 生产实例需要选择主备或者集群实例,不能选用单机实例 强烈建议 - 主备实例,不建议使用过大的规格。 建议 Redis在执行RewriteAOF和BGSAVE的时候,会fork一个进程,过大的内存会导致卡顿 具备降级或容灾措施 缓存访问失败时,具备降级措施,从DB获取数据;或者具备容灾措施,自动切换到另一个Redis使用。 建议 -
  • 应用场景 电商秒杀是一种网上竞拍活动,通常商家会在平台释放少量稀缺商品,吸引大量客户,平台会收到平时数十倍甚至上百倍的下单请求。但是只有少数客户可以下单成功。电商秒杀系统的分流过程可以分为以下几个步骤: 用户请求进入系统:当用户发起秒杀请求时,请求会首先进入负载均衡服务器。 负载均衡:负载均衡服务器会根据一定的算法将请求分发给后端多台服务器,以达到负载均衡的目的。负载均衡算法可以采用轮询、随机、最少连接数等方式。 业务逻辑处理:后端服务器接收到请求后,进行业务逻辑处理,并根据请求的商品数量、用户身份等信息进行校验。 库存扣减:如果库存充足,后端服务器会进行库存扣减操作,并生成订单信息,返回给用户秒杀成功的信息;如果库存不足,则返回给用户秒杀失败的信息。 订单处理:后端服务器会将订单信息保存到数据库中,并进行异步处理,例如发送消息通知用户订单状态。 缓存更新:后端服务器会更新缓存中的商品库存信息,以便处理下一次秒杀请求。 秒杀过程中多次访问数据库,下单通常是利用行级锁进行访问限制,抢到锁才能查询数据库和下单。但是秒杀时的大量订单请求,往往使数据库访问阻塞。
  • 大Key和热Key的影响 类别 影响 大Key 造成规格变更失败。 Redis集群变更规格过程中会进行数据rebalance(节点间迁移数据),单个Key过大的时候会触发Redis内核对于单Key的迁移限制,造成数据迁移超时失败,Key越大失败的概率越高,大于512MB的Key可能会触发该问题。 造成数据迁移失败。 数据迁移过程中,如果一个大Key的元素过多,则会阻塞后续Key的迁移,后续Key的数据会放到迁移机的内存Buffer中,如果阻塞时间太久,则会导致迁移失败。 容易造成集群分片不均的情况。 各分片内存使用不均。例如某个分片占用内存较高甚至首先使用满,导致该分片Key被逐出,同时也会造成其他分片的资源浪费。 各分片的带宽使用不均。例如某个分片被频繁流控,其他分片则没有这种情况。 客户端执行命令的时延变大。 对大Key进行的慢操作会导致后续的命令被阻塞,从而导致一系列慢查询。 导致实例流控。 对大Key高频率的读会使得实例出方向带宽被打满,导致流控,产生大量命令超时或者慢查询,业务受损。 导致主备倒换。 对大Key执行危险的DEL操作可能会导致主节点长时间阻塞,从而导致主备倒换。 热Key 容易造成集群分片不均的情况。 造成热Key所在的分片有大量业务访问而同时其他的分片压力较低。这样不仅会容易产生单分片性能瓶颈,还会浪费其他分片的计算资源。 使得CPU冲高。 对热Key的大量操作可能会使得CPU冲高,如果表现在集群单分片中就可以明显地看到热Key所在的分片CPU使用率较高。这样会导致其他请求受到影响,产生慢查询,同时影响整体性能。业务量突增场景下甚至会导致主备切换。 易造成缓存击穿。 热Key的请求压力过大,超出Redis的承受能力易造成缓存击穿,即大量请求将被直接指向后端的数据库,导致数据库访问量激增甚至宕机,从而影响其他业务。 对于如何避免产生大Key和热Key,需要在业务设计阶段就考虑。参考Redis使用规范。
  • 如何优化大Key和热Key 类别 方法 大Key 进行大Key拆分。 分为以下几种场景: 该对象为String类型的大Key:可以尝试将对象分拆成几个Key-Value, 使用MGET或者多个GET组成的pipeline获取值,分拆单次操作的压力。如果是集群实例,由于集群实例包含多个分片,拆分后的Key会自动平摊到集群实例的多个分片上,从而降低对单个分片的影响。 该对象为集合类型的大Key,并且需要整存整取:在设计上严格禁止这种场景的出现,因为无法拆分。有效的方法是将该大Key从Redis去除,单独放到其余存储介质上。 该对象为集合类型的大Key,每次只需操作部分元素:将集合类型中的元素分拆。以Hash类型为例,可以在客户端定义一个分拆Key的数量N,每次对HGET和HSET操作的field计算哈希值并取模N,确定该field落在哪个Key上,实现上类似于Redis Cluster的计算slot的算法。 将大Key单独转移到其余存储介质。 无法拆分的大Key建议使用此方法,将不适用Redis能力的数据存至其它存储介质,如SFS或者其余NoSQL数据库,并在Redis中删除该大Key。 注意: 禁止使用DEL直接删除大Key,可能会造成Redis阻塞,甚至主备倒换。 合理设置过期时间并对过期数据定期清理。 合理设置过期时间,避免历史数据在Redis中大量堆积。由于Redis的惰性删除策略,过期数据可能并不能及时清理,如果发现Redis过期Key清理较慢,建议配置过期Key扫描。 热Key 使用读写分离。 如果热Key主要是读流量较大,则可以在客户端配置读写分离,降低对主节点的影响。还可以增加多个副本以满足读需求,但是备机较多也有相应的影响,DCS主备节点之间使用的是星型复制,即所有的备节点都直接和主节点保持同步,这样能保证备节点之间相互独立,且复制延迟较小。缺点是在备节点数量较多的情况下,主节点的CPU和网络负载会较高。 使用客户端缓存/本地缓存。 该方案需要提前了解业务的热点Key有哪些,设计客户端/本地和远端Redis的两级缓存架构,热点数据优先从本地缓存获取,写入时同时更新,这样能够分担热点数据的大部分读压力。缺点是需要修改客户端架构和代码,改造成本较高。 设计熔断/降级机制。 热Key极易造成缓存击穿,高峰期请求都直接透传到后端数据库上,从而导致业务雪崩。因此热Key的优化一定需要设计系统的熔断/降级机制,在发生击穿的场景下进行限流和服务降级,保护系统的可用性。
  • 大Key和热Key的定义 名词 定义 大Key 大Key可以分为两种情况: Key的Value较大。一般单个String类型的Key大小达到10KB,或者集合类型的Key总大小达到50MB,则定义其为大Key。 Key的元素较多。一般定义集合类型的Key中元素超过5000个,则认为其为大Key。 热Key 通常以一个Key被操作的频率和占用的资源来判定其是否为热Key,例如: 某个集群实例一个分片每秒处理10000次请求,其中有3000次都是操作同一个Key。 某个集群实例一个分片的总带宽使用(入带宽+出带宽)为100Mbits/s,其中80Mbits是由于对某个Hash类型的Key执行HGETALL所占用。 说明:大Key和热Key场景较多,没有非常明确的边界,需要根据实际业务判断。
  • 场景介绍 在网页和APP中常常需要用到榜单的功能,对某个key-value的列表进行降序显示。当操作和查询并发大的时候,使用传统数据库就会遇到性能瓶颈,造成较大的时延。 使用分布式缓存服务(DCS)的Redis版本,可以实现一个商品热销排行榜的功能。它的优势在于: 数据保存在缓存中,读写速度非常快。 提供字符串(String)、链表(List)、集合(Set)、哈希(Hash)等多种数据结构类型的存储。
  • 实践指导 准备一台弹性云服务器(ECS),选择Windows系统类型。 在ECS上安装JDK1.8以上版本和开发工具(本文档以安装Eclipse为例),下载jedis客户端(点此处直接下载jar包)。 在华为云控制台创建DCS缓存实例。注意和ECS选择相同虚拟私有云、子网以及安全组。 在ECS上运行Eclipse,创建一个java工程,为示例代码创建一个productSalesRankDemo.java文件,并将jedis客户端作为library引用到工程中。 将DCS缓存实例的连接地址、端口以及连接密码配置到示例代码文件中。 编译并运行得到结果。
  • 运行结果 编译并运行以上Demo程序,结果如下: 商品热销排行榜 产品ID: product-b290c0d4-e919-4266-8eb5-7ab84b19862d, 销量: 18433 产品ID: product-e61a0642-d34f-46f4-a720-ee35940a5e7f, 销量: 18334 产品ID: product-ceeab7c3-69a7-4994-afc6-41b7bc463d44, 销量: 18196 产品ID: product-f2bdc549-8b3e-4db1-8cd4-a2ddef4f5d97, 销量: 17870 产品ID: product-f50ca2de-7fa4-45a3-bf32-23d34ac15a41, 销量: 17842 产品ID: product-d0c364e0-66ec-48a8-9ac9-4fb58adfd033, 销量: 17782 产品ID: product-5e406bbf-47c7-44a9-965e-e1e9b62ed1cc, 销量: 17093 产品ID: product-0c4d31ee-bb15-4c88-b319-a69f74e3c493, 销量: 16432 产品ID: product-a986e3a4-4023-4e00-8104-db97e459f958, 销量: 16380 产品ID: product-a3ac9738-bed2-4a9c-b96a-d8511ae7f03a, 销量: 15305 产品ID: product-6b8ad4b7-e134-480f-b3ae-3d35d242cb53, 销量: 14534 产品ID: product-26a9b41b-96b1-4de0-932b-f78d95d55b2d, 销量: 11417 产品ID: product-1f043255-a1f9-40a0-b48b-f40a81d07e0e, 销量: 10875 产品ID: product-c8fee24c-d601-4e0e-9d18-046a65e59835, 销量: 10521 产品ID: product-5869622b-1894-4702-b750-d76ff4b29163, 销量: 10271 产品ID: product-ff0317d2-d7be-4021-9d25-1f997d622768, 销量: 9909 产品ID: product-da254e81-6dec-4c76-928d-9a879a11ed8d, 销量: 9504 产品ID: product-fa976c02-b175-4e82-b53a-8c0df96fe877, 销量: 8630 产品ID: product-0624a180-4914-46b9-84d0-9dfbbdaa0da2, 销量: 8405 产品ID: product-d0079955-eaea-47b2-845f-5ff05a110a70, 销量: 7930 产品ID: product-a53145ef-1db9-4c4d-a029-9324e7f728fe, 销量: 7429 产品ID: product-9b1a1fd1-7c3b-4ae8-9fd3-ab6a0bf71cae, 销量: 5944 产品ID: product-cf894aee-c1cb-425e-a644-87ff06485eb7, 销量: 5252 产品ID: product-8bd78ba8-f2c4-4e5e-b393-60aa738eceae, 销量: 4903 产品ID: product-89b64402-c624-4cf1-8532-ae1b4ec4cabc, 销量: 4527 产品ID: product-98b85168-9226-43d9-b3cf-ef84e1c3d75f, 销量: 3095 产品ID: product-0dda314f-22a7-464b-ab8c-2f8f00823a39, 销量: 2425 产品ID: product-de7eb085-9435-4924-b6fa-9e9fe552d5a7, 销量: 1694 产品ID: product-9beadc07-aab0-438c-ac5e-bcc72b9d9c36, 销量: 1135 产品ID: product-43834316-4aca-4fb2-8d2d-c768513015c5, 销量: 256 商品热销排行榜 前五大热销产品 产品ID: product-b290c0d4-e919-4266-8eb5-7ab84b19862d, 销量: 18433 产品ID: product-e61a0642-d34f-46f4-a720-ee35940a5e7f, 销量: 18334 产品ID: product-ceeab7c3-69a7-4994-afc6-41b7bc463d44, 销量: 18196 产品ID: product-f2bdc549-8b3e-4db1-8cd4-a2ddef4f5d97, 销量: 17870 产品ID: product-f50ca2de-7fa4-45a3-bf32-23d34ac15a41, 销量: 17842
  • 制作客户端镜像 下载Redis客户端。 登录CCE集群节点。 单击创建完成的CCE节点池名称,进入CCE节点池,单击右上角的“远程登录”。 执行gcc --version检查操作系统是否安装了用于编译Redis程序的GCC编译器。如下图,表示已经安装了GCC编译器。 如未安装GCC编译器,请使用以下命令安装GCC编译器。 yum -y install gcc yum -y install gcc-c++ 执行以下命令,在home目录下创建redis目录,并进入该目录。 cd /home && mkdir redis && cd redis 执行以下命令下载Redis客户端。此处以下载5.0.13版本的客户端为例。 wget https://download.redis.io/releases/redis-5.0.13.tar.gz 解压Redis,进入Redis目录,执行编译命令后返回redis目录。 tar xvzf redis-5.0.13.tar.gz cd redis-5.0.13 && make redis-cli cd .. 创建Dockerfile。 使用vim Dockerfile命令创建Dockerfile,并填写以下信息。 FROM centos:7 RUN useradd -d /home/redis -m redis COPY ./redis-5.0.13 /home/redis/redis-5.0.13 RUN chown redis:redis /home/redis/redis-5.0.13 -R USER redis ENV HW_HOME=/home/redis/redis-5.0.13 ENV PATH=$HW_HOME/src:$PATH WORKDIR /home/redis/ 按下Esc键退出编辑模式,执行:wq!保存配置并退出编辑界面。 构建客户端镜像。 在控制台的服务列表中选择“容器镜像服务 SWR”,进入容器镜像服务总览页。 单击右上角“创建组织”,输入组织名称,新建一个组织。也可以使用已有的组织(单击左侧“组织管理”可查看已有组织。) 在SWR总览页单击右上角“登录指令”获取登录指令,复制登录指令。(登录指令结尾的swr.xxxxxx.com为镜像仓库地址。) 图1 获取登录指令 使用复制的登录指令在CCE节点中执行,登录SWR。 图2 登录SWR 执行以下命令构建镜像。 docker build -t {Image repository address}/{Organization name}/{Image name :version}. 其中Image repository address为镜像仓库地址,即登录指令的结尾部分;Organization name为b步骤创建的组织名称;Image name为需要构建的镜像名称,version为镜像的版本。请根据实际值进行替换。例如:docker build -t swr.xxxxxx.com/study1/redis:v1 . 图3 构建镜像 执行以下命令将客户端镜像上传到SWR。 docker push {Image repository address}/{Organization name}/{Image name :version} 图4 上传镜像 上传镜像后,可在SWR控制台“我的镜像”页面查看到Redis镜像。 图5 查看镜像
  • 测试工作负载 登录CCE集群节点,参考登录CCE集群节点。 参考通过kubectl连接集群,下载和配置kubectl配置文件。 执行以下命令,当返回状态为“Running”时,说明Redis容器处于运行状态。 kubectl get pod -n default 使用以下命令查看Redis容器的日志。 kubectl logs --tail 10 -f redis-xxxxxxxx -n default 其中redis-xxxxxxxx为创建的工作负载实例名称。(单击工作负载名称,进入工作负载,可查看工作负载实例名称。) 从返回信息中,可以看到DCS服务返回的信息为在前面连接Redis时设置的数据值“hello redis!”。 测试完成。
  • 前提条件 准备以下实例资源: 创建VPC和子网,例如vpc-test。创建方式请参考创建虚拟私有云和子网。 (可选)建议创建2个子网,将DCS实例放到一个子网,CCE集群放到另一个子网,方便管理。 创建DCS实例,例如dcs-test。创建方式请参考购买Redis实例。 创建的DCS实例时,“虚拟私有云”请选择所创建的VPC(vpc-test)及其子网1。 创建CCE集群,例如cce-test。创建方式请参考购买CCE集群。 创建CCE集群时,“网络模型”请选择“VPC网络";“虚拟私有云”和“子网”请选择所创建的VPC(vpc-test)及其子网2。 创建CCE节点池,例如cce-test-nodepool。创建方式请参考创建节点池。 创建CCE节点池时,“节点类型”请选择“弹性云服务器-虚拟机”,“容器引擎”请选择“Docker”,“操作系统”请选择“CentOS 7.6”,并需要绑定“弹性公网IP”,选择“使用已有”或“自动创建”。
  • 应用场景 游戏业务开合服,指一些大型网络游戏为了吸引新玩家,在运营一段时间后,会开启新服务区,当新服务区开放后,老服务区用户存在流向新服务区的趋势,用户数逐渐减少,为了改善老服务区用户的游戏体验,延长游戏生命周期,游戏开发商通常会进行新老服务区合并,将新开和原有的两个服务器(区)的数据合并到一个服务器(区),使新老玩家就能在同一个区进行游戏。在这个过程中,会遇到如何将不同服务器数据同步的相关问题。
  • 解决方案 使用分布式缓存服务(DCS)的Redis缓存在游戏开合服方面,可以应用到以下场景: 跨服数据同步 游戏合服后,需要将多个游戏服务器的数据进行同步,以保证游戏数据的一致性。可以使用Redis的消息队列pub/sub机制,将数据变更消息发布到Redis的频道中,其他游戏服务器订阅该频道,接收数据变更消息,从而实现数据同步。 跨服资源共享 游戏合服后,可以将多个游戏服务器的资源进行共享,例如玩家道具、金币等。可以使用Redis的分布式锁机制,来保证多个游戏服务器对资源的访问互斥,避免资源冲突。 跨服排行榜 游戏合服后,可以将多个游戏服务器的排行榜进行合并,以展示全服的排名情况。可以使用Redis的有序集合机制,来存储排行榜数据,并进行排名计算和查询。 在以上三种应用场景中,“跨服资源共享”的实现方式可以参考使用DCS实现热点资源顺序访问,“跨服排行榜”的实现方式可以参考使用DCS实现排行榜功能。 本篇文档主要介绍如何通过Redis的消息队列pub/sub机制,实现“跨服数据同步”。 在使用Redis进行游戏合服方面的应用时,需要考虑数据一致性、性能和安全等方面的问题,避免出现数据错误、性能瓶颈或者安全漏洞等问题。
  • 实施步骤 使用Redis-py库中的Redis()方法在每个游戏服务器上创建一个Redis客户端连接。 使用pubsub()方法在每个游戏服务器上创建一个Redis订阅者和发布者。用于订阅其他游戏服务器发布的消息,以及发布本地游戏服务器的数据更新消息。当某个游戏服务器需要更新数据时,它会将更新的消息发布到Redis消息队列中。其他游戏服务器会收到更新消息并相应地更新各自的本地数据。 定义一个publish_update()方法发布更新消息,并在listen_updates()方法中使用subscriber.listen()方法来监听更新消息。 当收到更新消息时,通过调用handle_update()方法来处理更新消息并更新本地数据。在游戏服务器中,通过调用publish_update()来发布更新消息,以及调用listen_updates()来监听更新消息。
  • 前提条件 已有MySQL数据库,并在其中创建一张表,作为源端数据库中的数据。 例如,在MySQL数据库中创建一张名为student_info的表格,表中共有4列,迁移后表中的id列的值将成为Redis中的hash的key,其余的列的列名将成为hash的field,而列的值作为field对应的value。 已创建DCS Redis实例,作为迁移的目的数据库。请参考创建DCS Redis缓存实例。 如果您的源端是华为云的MySQL数据库,Redis实例请选择与MySQL数据库实例相同的VPC。 已创建弹性云服务器ECS,且选择与Redis实例相同的VPC,操作系统为Linux。请参考购买并登录Linux弹性云服务器。
  • 解决方案 将Redis作为应用与数据库之间的缓存层可以解决上述问题,通过Redis缓存数据,提高数据读取速度,减轻数据库负载,提高应用性能,保证数据的可靠性。 因此,对于传统的关系型数据库例如MySQL,可以将其数据迁移到Redis中。Redis中的数据是以键值结构进行存储的,在迁移前需要将传统的数据库转换为特定的结构。本文以将MySQL数据库中的一张表迁移到华为云DCS Redis中为例,介绍数据迁移的过程。
  • 通过MobaXterm建立隧道作为跳板机 新建一个到ECS的SSH连接,使用22号端口。 图1 连接ECS SSH连接配置好后,输入登录用户和密码,连接上ECS。登录后输入TMOUT=0,避免连接超时自动关闭。 图2 输入TMOUT=0 在MobaXterm工具中找到MobaSSHtunnal,建立隧道。 图3 创建隧道 配置本地IP为127.0.0.1后,启动隧道。 图4 启动隧道 本地电脑打开Redis客户端,以Redis命令行界面为例。连接DCS缓存实例,命令如下: Redis-cli -h 127.0.0.1 -p 3306 -a {password} 参数说明: -h 主机名:localhost或者127.0.0.1,和隧道建立时配置的本地IP相同。 -p 端口号:3306,和隧道建立时配置的本地侦听端口相同。 -a 密码:DCS缓存实例连接密码。 连接成功,显示如下。 图5 连接实例
  • 通过Nginx访问Redis 登录ECS控制台,确认跳板机的安全组规则是否放开,如果没有,则需要为安全组放开8080和8081两个端口。 单击ECS实例名称,进入ECS详情页面。 选择“安全组”页签,单击“配置规则”,可进入安全组配置页面。 图6 进入ECS安全组 图7 添加安全组入方向规则 在公网环境中打开Redis命令行界面,输入如下命令,登录与查询都正常,大功告成。 公网环境已参考Redis-cli连接中相关步骤,安装Redis-cli客户端。 ./redis-cli -h {myeip} -p {port} -a {mypassword} 其中,命令中的{myeip}为主机连接地址,需要填写ECS的弹性IP,端口需要填写ECS上Nginx的监听端口。 如下图所示,设置的2个监听端口分别为8080和8081,对应后端2个Redis实例。 图8 通过Nginx代理连接第一个Redis实例 图9 通过Nginx代理连接第二个Redis实例 至此,就完成了通过跳板机的搭建,实现公网访问Redis的操作了。
  • (可选)长连接场景 如果用户公网访问时需要使用长连接,那么需要在如上配置Nginx中增加以下配置: Nginx到后端server的超时时间 stream { server { listen 8080; proxy_pass 192.168.0.5:6379; proxy_socket_keepalive on; proxy_timeout 60m; proxy_connect_timeout 60s; } server { listen 8081; proxy_pass 192.168.0.6:6379; proxy_socket_keepalive on; proxy_timeout 60m; proxy_connect_timeout 60s; } } proxy_timeout 默认值是10m,可以根据用户需要设为60m或其他值。Nginx官网 proxy_timeout说明 客户端到Nginx的超时时间 http { keepalive_timeout 3600s; } keepalive_timeout 默认值是75s,可以根据用户需要设为3600s或其他值。Nginx官网 keepalive_timeout 说明
共100000条