高性能数据访问中间件 OBProxy(五):一文讲透数据路由

news/2024/5/6 0:45:20/文章来源:https://blog.csdn.net/OceanBaseGFBK/article/details/127068366

上篇文章我们介绍了 OBProxy 的连接管理,通过连接管理功能,OBProxy 和 OBServer 联系起来,同时 OBProxy 屏蔽了连接的复杂性,让用户使用起来和单机数据库一样简单。完成接入后,接下来的一个重要功能就是数据路由,这也是大部分用户最关心的功能之一,本文会对其进行详细介绍。

在介绍 OBProxy 的路由原理前,我们先讨论下路由需要考虑的影响因素,方便你更好地理解后面的内容,以及评价一个路由功能的好坏。我将从功能、性能和高可用三个因素展开介绍。

数据路由影响因素

功能因素

你是否考虑过,一个单机数据库的功能如 MySQL 数据库的 Prepared Statements 功能,在分布式系统中该如何实现,比如 PREPARE Statement 和 EXECUTE Statement 该发往哪个节点?

我们以 Prepared Statements 功能为例说明功能对路由的影响。Prepared Statements 执行主要有两个步骤:

  • 步骤一:执行 PREPARE 操作,如发送SQL select * from t1 where c1 = ?
  • 步骤二:执行 EXECUTE 操作,传递 select 语句使用的数据,并执行 select

步骤二是依赖于步骤一的,我们假设执行情况如图1所示,你就会明白,当 OBServer2 收到步骤二( EXECUTE)的请求后,并不知道步骤一(PREPARE)请求的内容,这时,OBServer2 就会报错(优雅做法)或断连接(粗暴做法)。

2.png
图1 PS功能执行情况

对于这种问题,常见的解决办法有两种(见图2)。

  • 方法一:记录 PREPARE 路由到的节点 OBSERVER1,EXECUTE 请求继续路由到 OBServer1;该方法实现简单,但无法发挥分布式系统的优势。
  • 方法二:在执行 EXECUTE 前,将 PREPARE 的状态同步给 OBServer2,参考连接管理部分的状态同步;该方法需要 OBProxy 同步连接状态,实现复杂,但可以利用分布式系统的优势,目前 OBProxy 采用了该方法。

3.png图2 解决路由失败的两个方法

性能因素

高性能是 OceanBase 数据库的重要特性,路由对性能的影响主要是延迟,即网络通信开销。OBProxy 通过感知数据分布和机器地理位置降低网络通信开销,提高整体性能。

数据分布主要影响执行链路的跳数,OBProxy 路由时直接命中数据所在的节点是最好的。我们以 SQL 语句 select c1 from test为例说明数据分布对性能的影响。如图3所示,t1表的数据分布在 OBServer1 上面,路由方式1直接路由到 OBServer1 ,效率最高;路由方式2发给了一个无t1表数据的 OBServer2,OBServer2 再进行路由转发给 OBServer1,相比方式1性能变差。为了实现路由方式1的路由,OBProxy 需要感知SQL和表数据分布,后文会详细介绍。4.png图3 OBProxy 的两种路由方式

机器地理位置主要影响网络延迟,当选择了一个远端节点后,SQL执行会变慢,有时网络延迟的时间比数据库执行时间要大很多。我们在阿里云上做了测试,延迟数据如下:

  • 杭州同可用区 rtt min/avg/max/mdev = 0.111/0.141/0.433/0.060 ms
  • 杭州不同可用区 rtt min/avg/max/mdev = 1.847/2.003/5.840/0.740 ms

可以看到跨可用区后延迟增加接近2ms,对于简单SQL,数据本身执行时间可能才100us左右。因此,**对于不同地理位置的机器,OBProxy 选择优先级是:同机房>同城不同机房>不同城市。**图4展示了优先选择同城市的OBServer1。5.png图4 优先选择同城市的OBServer1

高可用因素

高可用因素是指 OceanBase 数据库对机器故障有容忍能力,让故障对应用透明无感知,**OBProxy 发现 OBServer 节点故障后,路由时会排除故障节点,选择健康节点,对于正在执行的SQL也有一定的重试能力。**高可用涉及故障探测、黑名单机制、重试逻辑等内容。如图5所示,OBProxy 发现OBServer1 故障后,将该节点加入黑名单。路由时从健康节点选择。6.png
图5 OBProxy 发现 OBServer 节点故障的处理逻辑

了解了数据路由的影响因素和路由原则后,我们就可以更高效地进行路由策略设计了。不过,现实情况会复杂很多,原则上我们要实时感知 OBServer 状态、数据分布等,但在工程实践中很难做到,便引发出许多问题。因此,我们在**考虑路由时需要兼顾功能、性能和高可用,**让 OceanBase 数据库“更好用”。

OBProxy 路由功能

我们知道通过 OBProxy可以访问不同集群的不同租户的不同机器。这也是 OBProxy 可以实现集群路由、租户路由和租户内路由的原因,接下来我将围绕这三部分介绍OBProxy的路由功能。

集群路由

集群路由是指 OBProxy 路由功能支持访问不同的集群,它的关键点在于获取集群名和rslist的映射关系(见图6):

  • 对于启动参数指定rslist的启动方式,集群名和rslist的映射关系通过启动参数指定
  • 对于指定config_server_url的启动方式,集群名和rslist的映射关系通过访问url获取

需要注意的是,**这里的rslist不需要包含所有的集群机器列表,OBProxy 会通过访问内部表获取集群所有机器,**一般rslist为RootServer(OceanBase的总控服务)所在的机器。7.png图6 集群路由步骤

我们从图6中可以看到,OCP 是集群路由时非常重要的一个模块。当出现集群路由问题时,大部分都是 OCP 模块出现了问题,常见等问题有两个。

  • OCP 服务不可用:OBProxy 无法通过 OCP 获取集群名和rslist的映射关系,导致登录失败。
  • OCP 返回错误的结果:如 OBProxy 通过HTTP协议访问OCP,获取结果,结果为JSON格式,如果格式有问题,会导致结果解析失败。

OBProxy 是在用户登录首次访问集群时获取rslist,并保存到内存中,后续再访问该集群,从 OBProxy 的内存中获取就可以了。这里需要注意,当集群内存信息创建好后,OCP再出现问题,即使OBProxy 仍可以正常工作,也要及时排查 OCP 问题。

租户路由

OceanBase 数据库中,一个集群有多个租户,租户路由是指 OBProxy 路由功能支持访问不同的租户。在众多租户中,sys租户比较特殊,类似于管理员租户,和集群管理相关。我们将分开讨论sys租户路由和普通租户路由。

1. sys租户路由

完成集群路由后,我们可以获得集群的rslist,此时 OBProxy 会通过proxyro@sys账号登录rslist中的一台机器,并通过内部表__all_virtual_proxy_server_stat获取集群的所有机器节点。在 OceanBase 数据库的现有实现中,sys在每个节点都有分布,因此,__all_virtual_proxy_server_stat返回的结果也就是sys租户的路由信息。

OBProxy 会15秒访问一次__all_virtual_proxy_server_stat,维护最新的路由信息,这样集群发生节点变更都可以感知到。

除了集群机器列表,OBProxy 还会通过sys租户获取partition分布信息、zone信息、租户信息等。可见sys租户对 OBProxy 非常的重要。

2. 普通租户路由

sys租户的路由信息就是集群的机器列表,但普通租户不同,普通租户路由信息就是租户资源(unit是CPU、内存、磁盘等资源载体,详情可查阅 OceanBase 数据库名词概念)所在的机器。

注意:由于历史原因,查询租户路由信息并不是通过unit相关的表,而是通过特殊表名__all_dummy表示查询租户信息。OBProxy 需要通过内部表__all_virtual_proxy_schema获取租户的机器列表,在访问__all_virtual_proxy_schema时,OBProxy 指定表名(_all_dummy)和指定租户名获取租户的节点信息。图7展示了租户的路由信息。

图7 普通租户路由信息

当获取到租户信息后,OBProxy 会保存在本地内存中,并根据一定策略进行缓存信息的更新。对于 sys 租户,通过15秒一次的拉取任务获得最新的信息;对于普通租户,而刷新频率并不高,普通租户的路由缓存策略如下。

  • 创建:首次访问租户时,通过__all_virtual_proxy_schema获得普通租户路由信息并创建。
  • 淘汰:当 OBServer 返回错误码 OB_TENANT_NOT_IN_SERVER时设置缓存失效。
  • 更新:当缓存失效后重新访问__all_virtual_proxy_schema获得普通租户路由信息。

总的来说,在多租户架构下,OBProxy 通过 sys 租户获得元数据信息,sys租户本身路由信息就是集群的机器列表,然后通过元数据信息获得租户的路由信息。通过租户路由功能,OBProxy 支持了 OceanBase 数据库的多租户架构。

租户内路由

租户内路由是指在获取租户的机器列表后,选择合适的节点执行SQL。

对于租户内路由,OBProxy 可以像普通代理如 HAProxy 一样,一个客户端连接对应一个服务端连接,服务端机器从租户机器列表选取,这样功能就会简单很多,但无法满足性能和高可用要求,可见路由影响了连接管理。

租户内路由是路由功能最复杂的部分,主要原因是在想办法提供更好的性能和更高的可用性。我将按照主副本路由、备副本路由、租户机器路由、缓存信息、路由策略、事务路由和常见问题这七部分为你介绍。为什么是这样的顺序呢?你可以在阅读完本文后尝试梳理思维导图,感受更深。

1. 主副本路由

在分布式系统中,为了容灾高可用,会采用多副本机制。副本之间需要保证数据一致性,往往采用Paxos或者Raft算法,在工程实践中,有一个特殊副本,该副本数据最新,并控制数据在副本间的同步,这个副本叫做主副本,其它副本叫做备部分。

由于 OceanBase 数据库只有一个主副本,因此,主副本路由策略就是发往该副本。我们以select c1 from t1为例,介绍主副本路由需要满足的两个条件:

  • SQL语句操作(查询、插入、更新和删除等)实体表,上面例子是t1表。
  • 请求必须读到最新数据,即强读(和弱读对应,弱读不要求读到最新数据)。

在 OBProxy 日志中,主副本路由的关键字是ROUTE_TYPE_LEADER。要实现主副本路由,就需要知道访问的分区标识和分区所在的位置。在 OBProxy 的实现中,分为两种情况。第一种情况是单分区表,表只有一个分区,根据表名就可以获得副本位置信息;第二种情况是多分区表,表有多个分区,OBProxy 需要根据SQL中的表名和分区键计算出分区标识,再获取副本位置信息。副本信息包含主副本信息和备副本信息,主副本路由只需要使用主副本信息。

对于多分区路由,涉及分区方式(如hash、range和list)、分区键类型(number、varchar等)、分区算法(如hash算法)、类型转换(如SQL中的值类型和分区键类型不同)等知识点,实现比较复杂,我们以二级分区为例介绍,分为10个步骤(见图8)。

9.png图8 多分区路由流程

2. 备副本路由

了解完主副本路由策略后,你一定想到了备副本路由。备副本路由也需要满足两个条件:SQL语句查询实体表,上面例子是t1表;请求要求弱读即可。

这两个条件和主副本路由需要满足的条件是有区别的:

  • 对于条件1,备副本路由只支持查询语句,不支持其他语句,这也是Paxos算法的实现要求。
  • 对于条件2,需要主动设置弱读标记ob_read_consistency=weak,可以通过hint、session等设置。

对于备副本路由,发往主副本和备副本都可以正常工作,因此备副本路由可以选择变多了**(**对于多个副本选择的问题,请参考下文“路由策略”的内容)。在很多时候,你可能认为备副本路由只能发往备副本,而实际上发往主副本也可以正常工作

和备副本相关的一个重要话题就是读写分离,请求进行读写分离后,可以降低主副本压力,是一个很好用的功能。OBProxy 也实现了读写分离功能,并在不断打磨细节,在 OceanBase 公有云等场景帮助客户解决了性能问题。

3. 租户机器路由

有些时候我们无法获取主副本或备副本,此时就可以从租户机器中选取一台,这就是租户机器路由。
常见的租户机器路由场景如下:

  • SQL 本身不包含表名,如语句select 1语句。
  • 主副本或者备副本所在的机器有故障。
  • OBProxy 本身功能限制,如复杂 SQL 无法获得表名,无法走副本路由。

通过租户机器路由,OBProxy 将 SQL 发往了租户所在的机器,因此可以保障功能正常。租户机器路由和备副本路由一样,有多个副本可以选择,也存在着路由策略的问题。

4. 缓存信息

主副本路由、备副本路由和租户机器路由都需要通过sys租户查询副本路由信息,为了提升性能和降低对sys租户的压力,OBProxy 对路由信息做了缓存。对于缓存信息,最重要的是时效性。你可以对比sys租户的缓存信息更新,sys租户的缓存信息可以通过定期访问内部表创建和刷新,那么副本路由的缓存信息是否可以采用此策略呢?

答案是:不可以。主要问题是拉取副本路由信息的SQL太多,会对sys租户造成很大的压力。SQL的数量 = 副本的个数 * OBProxy的数量。

OceanBase 数据库可以支持十万、百万分区,分区数极大。OBProxy 的数量受到部署架构影响,部署在应用端形态下,数量也很多。因此,缓存时效性对 OBProxy 是一大难题,使用了过期的缓存信息就会出现大家常说的“路由不准”的问题。那么,怎么保证缓存的时效性呢?

我们先看一下缓存信息在 OBProxy 中的内容。使用root@proxysys账号登录,通过show proxyroute命令可以查看表的缓存信息,如下:

MySQL [(none)]> show proxyroute like 'ob1.hudson tt1 test sbtest1'\G
*************************** 1. row ***************************cluster_name: ob1.hudsontenant_name: tt1database_name: testtable_name: sbtest1state: AVAILpartition_num: 1replica_num: 3table_id: 1101710651081698cluster_version: 2schema_version: 1649196335597728from_rslist: Ncreate_time: 2022-04-07 12:41:16last_valid_time: 2022-04-07 12:41:16last_access_time: 2022-04-07 12:41:16last_update_time: 1970-01-01 08:00:00expire_time: 2022-04-12 12:48:42
relative_expire_time: 2022-04-07 12:40:41server addr: server[0]=xx.xx.xx.xx:xx,leader,FULL; server[1]=xx.xx.xx.xx:xxfollower,FULL; server[2]=xx.xx.xx.xx:xx,follower,FULL;

这个例子展示了缓存包含的重要信息:集群名、租户名、库名、表名、分区数、副本数、时间、地址信息和缓存状态等。其中,缓存状态是需要我们重点关注的对象,缓存策略都是通过修改状态信息实现的,这些状态影响缓存的刷新机制。缓存信息分为如下5个状态。

  • BUILDING状态:缓存正在创建,需等待创建完成然后使用。
  • AVAIL状态:缓存正常,直接使用即可。
  • DIRTY状态:缓存失效,信息不准确。
  • UPDATING状态:失效的缓存正在更新过程中。
  • DELETED状态:缓存已经备删除,不可以使用,后续会被清理掉。

我们通过修改缓存状态就能刷新缓存状态,从而保证时效性,下面从创建、淘汰和刷新这三方面介绍缓存刷新机制。

  • 缓存创建:首次访问分区时,OBProxy 通过查询 sys 租户 的 __all_virtual_proxy_schema获得,指定表名为真实表名,注意和租户路由信息部分区分,创建好后缓存状态为AVAIL 。
  • 缓存淘汰:当 OBServer 返回路由不准时(ObServer 会通过OK报文中携带的is_partition_hit字段反馈),OBProxy 修改缓存状态为 DIRTY
  • 缓存刷新:当缓存信息变为DIRTY状态后,淘汰过期缓存,并重新创建或者更新缓存信息。

目前缓存淘汰主要通过 OBServer 的报文反馈实现,这样就无法实时感知,只有出现一次“错误”路由后,才能刷新,这也是容易出问题一个地方。

5. 路由策略

5.1 路由策略介绍

路由策略用于从多副本中选择出一个合适的副本。这里的多副本,可能来自备副本路由时选择出的多个副本,也有可能是类似select 1 from dual这种语句,使用了租户的路由信息有多个副本(指租户的机器列表)。

路由策略主要有三种:LDC路由、Primary Zone路由和随机路由,路由策略优先级为 Primary Zone路由 > LDC路由 > 随机路由。

**1)Primary Zone路由。**在多副本选择时,优先发往Primary Zone(租户的属性,Primary Zone指副本的Leader优先分布在Primary Zone中)所在的机器。为什么会有这种路由策略?首先,OceanBase 中常用的高性能部署架构是租户的 Primary Zone 在一台机器,这样可以避免分布式系统的很多网络开销;其次,OBProxy 在主副本路由时,存在找不出表名和计算不出分区的情况,通过Primary Zone路由可以尽量发往主副本。

2)LDC路由是基于地址位置的路由,有两个重要的概念:IDC和Region。IDC表示逻辑机房概念,Region是城市的概念。OBProxy 和 OBServer 都可以设置LDC信息。通过LDC信息,OBProxy 可以确定和 OBServer 的位置关系。当我们设置了LDC信息后,OBProxy就会默认使用LDC路由。

  • ** OBServer LDC设置。**

OBserver 的每个Zone都可以设置Region属性/idc属性,Region通常代表城市的概念,通常设置为城市名(大小写敏感),IDC代表该Zone所处的机房信息,通常设置机房名(小写)。设置SQL如下:

alter system modify zone "z1" set region = "SHANGHAI";
alter system modify zone "z1" set idc = "zue";

select * from __all_virtual_zone_stat;
图9 ** **OBServer LDC设置

  • OBProxy设置LDC。

OBProxy通过配置项或者启动参数设置LDC信息。首先通过-i选项设置启动参数,然后执行配置项:执行SQL语句alter proxyconfig set proxy_idc_name='机房名';通过 OBProxy 执行内部命令show proxyinfo idc;可以检查proxy内部识别的LDC部署情况。

图10 OBProxy设置LDC

你一定在想有没有最佳实践,确实有。如果只有一个机房,LDC用处不大,因为我们认为同机房机器间延迟相同。如果在同机房要使用LDC,需要划分出LDC架构,并设置 OBServer 和 OBProxy 的LDC属性。如果有多个机房,就可以根据机房和城市设置LDC,如公有云杭州可用区I、H机房,它们Region相同,IDC名字不同。

某些特殊情况下,可以通过trick方法设置LDC影响LDC路由,但不太推荐你这么做。

**3)随机路由。**通过优先级路由后,如果还有多个副本,进行随机路由即可。如未开启Primary Zone路由或者未设置LDC路由,就会直接使用随机路由。

5.2 路由配置和查看

数据路由比较复杂的一个原因是有不同的路由策略,OBProxy默认策略是先进行主副本路由和备副本路由,没有副本则进行租户机器路由。如果只有一个副本被选中,则直接路由,否则根据策略路由。

对于 Primary Zone 路由和 LDC路由,受到配置项控制:

  • enable_primary_zone:为true表示使用 Primary Zone路由策略
  • proxy_idc_name:内容非空(内容为 idc 的名字)表示使用LDC路由

除了现有路由策略,有时我们想使用其它路由策略,可以通过修改配置项proxy_route_policy控制实现,设置后新策略优先级最高。目前我们经常设置的其它路由策略有两种,都和弱读有关。

  • “FOLLOWER_FIRST”:优先发往备副本,如果无备副本可用发往主副本。
  • “FOLLOWER_ONLY”:只能发往备副本,如果无备副本可用报错。

OBProxy 具体使用了什么路由策略,可以在 OBProxy 的日志中查看关键信息route_type,如ROUTE_TYPE_LEADER表示进行了主副本路由。ROUTE_TYPE_NONPARTITION_UNMERGE_LOCAL情况比较复杂,下面介绍主要关键字含义。

  • PARTITON:选取有副本数据的机器,不区分副本的类型。
  • NONPARTITION:不关心表数据分布,任何租户机器都可以。
  • FOLLOWER:发往备副本。
  • LEADER:发往主副本。
  • UNMERGE:发往不在合并状态的机器。
  • MERGE:发往在合并状态的机器。
  • LOCAL:发往同IDC(机房)机器。
  • REMOTE:发往同城不同IDC(机房)机器。
  • REGION:发往异地的机器。
  • READONLY:发往READONLY属性Zone内机器。
  • READWRITE:发往READWRITE属性Zone内机器。
  • DUP:复制表中,发往复制表所在的机器。

对于该问题,你也可以参考《高性能数据访问中间件 OBProxy(三):问题排查和服务运维》。

6. 事务路由

上面介绍了单个SQL的路由策略,有些功能如事务功能包含一条或多条SQL。对于事务路由,事务的第一条语句受到上述策略影响,后续SQL不再进行路由,直接发往第一条语句发往的节点。

为什么事务路由只能发往第一条语句发往节点?你可以参考数据路由影响因素中的“功能因素”。目前我们还未实现事务状态迁移,所以有此限制。

7. 常见问题

相信当你看到限制要求后,感觉到此处可能有坑。下面我按照本文的叙述顺序说明常见的坑。

  • 无法获取表名(主副本路由)
    • SQL太复杂,目前 OBProxy 无法识别所有的SQL语句
    • SQL太长,OBProxy 存储SQL的buffer只有4K,SQL太长不会全解析
  • 分区计算失败(主副本路由)
    • OBProxy 无法支持多分区键的计算如range(c1,c2);
    • SQL语句中没有分区键的表达式或者 OBProxy 未提出出来
    • 分区键表达式 OBProxy 无法处理,如c1=now(),OBProxy还未支持now函数
  • 使用过期缓存(缓存信息)
    • OBProxy 无主动刷新机制
    • OBServer未进行路由反馈(如分布式计划 OBServer 不反馈)
  • 配置错误:
    • 未设置路由策略为FOLLOWER_FIRST,弱读发往了主副本(备副本路由)
    • 未设置LDC路由信息或者信息设置错误导致跨机房或者跨城(路由策略)

总结

数据路由功能点很多,并且功能点之间存在优先级问题,会让路由变得复杂。考虑性能和高可用因素,OBProxy 路由功能还有一些可以完善的地方,如 增强 Parser 能力、支持多分区键路由计算、提高缓存实效性等。我们也在不断提高路由能力,解决大家的问题。

课后互动

上期互动答案

问:JDBC和OBProxy建立了一个连接,晚上OBProxy被kill掉重启,请问此时JDBC会抛出异常吗?

答:不会的。因为JDBC不感知 tcp 异常,所以只有在真正使用连接时才会发现连接出现问题,这种问题就会比较难排查。大家可以看JDBC的异常日志会打印上次发给 Server 的请求时间和上次从Server接收到请求的时间,如果接收请求的时间大于发送请求时间,那么上次请求应该是正常完成,可能就是上来就拿到了一个坏连接。

本期互动问题

问:对于一个有表名的强读请求,如果SQL长度为7K,那么可能会如何路由?

欢迎你在问答区发帖讨论,下篇文章揭晓答案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_203666.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[luogu3980]志愿者招募

记$x_{i}$为第$i$类志愿者数量$,y_{j}=\sum_{j\in [s_{i},t_{i}]}x_{i}-a_{j}$​,则问题即$$\forall i\in [1,m],x_{i}\ge 0\\\forall j\in [1,n],y_{j}\ge 0\\y_{1}-\sum_{s_{i}=1}x_{i}=-a_{1}\\\sum_{t_{i}=n}x_{i}-y_{n}=a_{n}\\\forall j\in [2,n],y_{j}+\sum_{t_{i}=j-1…

redis主从+哨兵+集群模式搭建详解

一、redis主从安装 1. 下载redis Download | Redis 我这里选择的是redis-6.2.7版本 这里三台机器,都需要安装redis node1 192.168.157.128 node2 192.168.157.129 node3 192.168.157.130 2. 安装redis # 解压redis tar -zxvf redis-6.2.7.tar.gz # 编译安装…

数据分析 面经(已拿到offer)

北航计算机专业(计院太卷,现考虑转向信息安全方向)本科二年级,闲来无事找份日常实习试试水 考虑数分岗也是因为楼主目前大二,专业课学习不够深入,开发技术尚不成熟,而sql、excel和数据可视化比…

四元数是什么

1、四元数的构成 四元数是简单的超复数,由实数加上三个虚数单位组成,主要用于在三维空间中表示旋转 四元数原理包含大量数学相关知识,较为复杂,比如:复数、四维空间等等 因此此文章只对其基本构成和基本公式进行学习…

多视图属性网络异常检测系列一

论文《Deep Anomaly Detection on Attributed Networks》近期会对多视图属性网络异常检测系列进行学习记录 这篇虽然不是多视图的,但可以说是属性网络上异常检测的典型,已是近年属性网络异常检测必参考的一篇文献。背景 由于属性网络中附加的节点属性补充了知识发现中的原始网…

.Net Redis的秒杀Dome和异步执行

1.先到官网下载Redis部署好 Redis 教程 | 菜鸟教程 2.创建一个上游业务项目(这里用控制台项目了,Framwork4.7.2) NuGet包下载SerivceStack.Redis 创建一个RedisMessgaeQueue(Redis连接帮助类) using ServiceStack.Redis; using System;name…

PCIe系列专题之三:3.0 数据链路层概述

一、故事前传 之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-based layered protocol),主要包括事务层(Transaction layer), 数据链路层(Data link layer)和物理层(Physi…

MySQL 常用数据类型说明

目录 MySQL中常用的数据类型 整型 整型声明 整型属性 整型的选择 浮点型 定点数类型 浮点数和定点数的区别 时间日期类型 DATE类型 TIME类型 DATETIME类型 YEAR类型 文本字符串 CHAR与VARCHAR类型 TEXT类型 ​编辑 枚举类型(ENUM) MySQL中常用的数据类型 数据类…

直播平台怎么搭建,实现js开光灯效果

直播平台怎么搭建,实现js开光灯效果<!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>点击切换灯亮</t…

Spring容器与依赖注入(DI)

1 Spring框架简介 1.1 什么是Spring Spring框架是一个开源的轻量级的DI和AOP容器框架&#xff0c;致力于简化企业级应用开发&#xff0c;让开发者使用简单的Java Bean来实现从前只有EJB才能实现的功能。 1.2 为什么要使用Spring Spring堪称Java世界中最强大的框架&#xff0c;…

单调栈题目:柱状图中最大的矩形

文章目录题目标题和出处难度题目描述要求示例数据范围解法思路和算法代码复杂度分析题目 标题和出处 标题&#xff1a;柱状图中最大的矩形 出处&#xff1a;84. 柱状图中最大的矩形 难度 7 级 题目描述 要求 给定整数数组 heights\texttt{heights}heights 表示柱状图中…

正弦信号发生器的设计

目 录 1 引言 1 2 总体结构设计 2 2.1 单片机概述 2 2.1.1 单片机的发展 2 2.1.2 单片机的用途 3 2.2 系统设计的功能 3 2.3 波形发生和输出频率的方法 4 2.3.1 波形发生的方法 4 2.3.2 输出频率的方法 4 3 系统硬件设计 5 3.1 硬件电路芯片的选择 5 3.1.1 CPU芯片 AT89C51 5 3…

MyBatis中的复杂映射

上一章中实现的MyBatis对象映射较为简单&#xff0c;对象中的属性和数据库中的表字段是一一对应的&#xff08;无论数量和名称都完全一样&#xff09;&#xff0c;如果对象中的属性名和表中的字段名不一致怎么办&#xff1f;又或者Java对象中存在复杂类型属性&#xff08;即类似…

百分点数据科学产教融合计划继续扩大招募

从全球发展来看&#xff0c;数字经济已经成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量&#xff0c;是全球共同的发展战略。作为新经济中的数据科学&#xff0c;伴随社会各领域对数字人才需求的与日俱增&#xff0c;也成为了这一波科技革命中的人才竞争…

中国新出海故事:人、疫情与纽带

【潮汐商业评论/原创】 《枪炮、病菌与钢铁》中对人类社会发展的洞察与新千禧年发生了奇妙的呼应&#xff0c;战争、疫情成为了这十年的历史注脚&#xff0c;但时代的车轮总是滚滚向前的&#xff0c;新的世界版图里&#xff0c;全球化、数字化的浪潮构成了新世界跳动的脉搏&am…

第2章 ROS 通信机制 4 —— 常用命令

文章目录1 应用场景2 rosnode 功能包 plumbing_pub_sub编译执行3 rostopic 功能包 plumbing_pub_sub编译执行4 rosservice (服务通信) 功能包 plumbing_server_client编译执行5 rosmsg (话题通信) 功能包 plumbing_pub_sub编译执行6 rossrv (服务通信) 功能包 plumbing_server_…

常见网络知识面试题总结

&#x1f353;个人主页&#xff1a;个人主页 &#x1f352;系列专栏&#xff1a;C/C基础与进阶 &#x1f4ac;推荐一款模拟面试、刷题神器&#xff0c;从基础到大厂面试题&#x1f449;点击跳转刷题网站进行注册学习 目录 1、OSI七层模型与TCPIP四层模型是什么&#xff1f; 2…

核爆!字节跳动算法大佬手写1000页数据算法笔记:Github已标星79k

数据结构是什么 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下&#xff0c;精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。 算法是什么 算法是对解题方案…

PC 端网页特效

一、元素偏移量 offset 系列 (一)offset 概述 1、offset 翻译过来就是偏移量,我们使用 offset 系列相关属性可以动态的得到该元素的位置(偏移)、大小等。 (1)获得元素距离带有定位父元素的位置; (2)获得元素自身的大小(宽度高度); (3)注意:返回的数值都不带单位…

使用polkadot.js在substrate frontier上安装ERC20token合约

使用polkadot.js在substrate frontier上安装ERC20token合约参考资料Substrate Frontier Node Template github.com/substrate-developer-hub/frontier-node-template frontier-node-template/examples/contract-erc20/truffle/contracts/MyToken.json安装ERC20 token合约 sourc…