热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于python:基于-MaxCompute-Hologres-的人群圈选和数据服务实践

简介:本文次要介绍如何通过MaxCompute进行海量人群的标签加工,通过Hologres进行剖析建模,从而反对大规模人群简单圈选场景下的交互式体验,以及基于API的数据服务最佳实际。

简介: 本文次要介绍如何通过 MaxCompute 进行海量人群的标签加工,通过 Hologres 进行剖析建模,从而反对大规模人群简单圈选场景下的交互式体验,以及基于API的数据服务最佳实际。

本文作者 刘一鸣 阿里云智能 高级产品专家

人群圈选零碎根本逻辑架构

人群圈选并不是一个新业务, 简直所有的互联网公司都在做,因为这是一个根本营销场景,选定的人群要发代金券,要导入流量,要做针对性促销,要抉择适合的人群,那怎么做这件事件呢?实际上要通过人群的行为特色,洽购个性,关注特色,趣味个性,甚至是教育水平等等,把人群划分成不同的组。通过划分人群组,在无限的营销估算外面,将资源投放给转化率或点击率最高的人群。

根本的业务架构逻辑如下图,自下而上。首先是标签加工引擎,次要以离线加工为主。在标签加工引擎内,会对用户历史的洽购行为、拜访行为、关注行为等等做很多标签,能够统计进去,哪些人对哪些商品关注过多少次,点击过多少次,注意过多少次等等,会有很多统计性的属性在外面。这些标签会导入到在线画像服务引擎内,服务引擎是给经营人员,广告主进行交互式的查问,因为要依据用户行为特色,筛选出最关注的用户群体。这个用户群体可能是30天内关注某些商品然而没有买的群体,或者是相干的上下游产品,通过行为特色筛选进去。筛选过程是一个高度交互过程,因为一个人的行为特色是非常复杂的。所以须要频繁的抉择某个条件,去掉某个条件,条件和条件之间可能会做合并、去重的操作等等。直到把人群大小限定到估算可反对的范畴内,比方咱们要投递给1万集体广告,那要通过各种限定条件把这1万集体找进去。找进去还不能做间接投递,还须要对人群做更细粒度的剖析,通过历史数据行为剖析这1万集体是不是想要的指标人群。之后会把目标群体以投递包的模式,导出给投递零碎。这是一个根本业务逻辑。

那这个业务需要的背地技术要求是什么呢?

典型人群业务版块的外围是洞察剖析,洞察剖析个别的场景是,要撑持几万个不同的广告主,他们会在平台上自由选择更感兴趣的人群,每个广告主对人群的诉求是不一样的,某些人关注的购买力,有些关注的是珍藏行为。每天数万广告主收回数百万次的查问申请,构建数万次各种人群包,各个系统的计算复杂度是要求十分高的。这里的外围诉求蕴含几个点,毫秒级洞察,因为所有的查问心愿是交互式的,须要在界面上每一次互动,每一次下拉菜单,每一次抉择,每一次条件组合,都心愿看到一个互动后果,整个人群是变大还是变小,指标人群是不是跟冀望的类似。这一点对性能要求是十分大的。同时揭示大家,数据肯定要脱敏解决,爱护好用户的个人隐私,所有的剖析都是建设在合规数据根底之上的剖析。

人群圈选零碎服务引擎外围诉求

规模数据上的交互式剖析性能

数万广告主提交数百万次的数据查问,须要毫秒级的响应,查的快是必须的。这个快加了一个限定词,是规模数据。百万级不算规模,行为日志是十分大的,心愿是百亿级别以上,仍旧有一个很好的交互式剖析能力,可能在秒级响应。

灵便筛选能力

用户的筛选行为多种多样,等值比拟、数值大小范畴比拟、工夫范畴比拟等。各种各样的筛选条件可能灵便组合,表白这些筛选后果就体现进去计算引擎的能力。

高吞吐更新能力

用户标签并不是动态的,以后所有实时化,所有在线化,所有的行为数据变动,都心愿可能实时触发,实时反馈下一时刻的零碎决策。比方最新收藏夹里放了什么商品,这种行为能不能成为在线画像的一部分。所以对高实时的吞吐能力要求会很高。

从计算层面来讲,能够分成下图几种计算模式。

标签过滤分为等值过滤,能够用Equal/In/Between,这些过滤能够在百亿级别上进行操作。操作之后的后果集,要做很多的交差并集,举个常见例子,一个用户既关注了竞品品牌也关注了本公司商品,却没有买,这外面其实有并的关系,有差的关系,有交的关系。所以这些人群关系之间要组合,有很高的交差并集计算。最初还有很强的准确去重的需要,因为最终要把计算结果,变成一个惟一定位用户的ID,这个ID会用来做广告的投递。那这些需要,在引擎层面上就是数据读取效率怎么样,如果用行存读取是不是会呈现IO放大的问题,数据按行去存,真正过滤是依照某一列过滤,然而IO读取,会把整行读取,会呈现IO放大问题。列存还会有索引问题、过滤成果问题。计算算子上表连贯时是Hash JOIN形式还是用Nest Loop JOIN形式。准确去重的成果如何。这些都是对计算引擎效率上有很高的要求。所以实质上是要解决高效数据存储与过滤、关系运算内存/CPU耗费、准确去重内存/CPU耗费问题。

这里就有很多不同的解决优化思路,是用更多的内存还是CPU。行业内大抵的思路有两种。

一种是通过预结算思路,有Kylin/Druid这样的技术。这些技术能够在一些预约义的维度上,进行一次提前的预加工。预加工后,数据集会在实质上进行缩小。比方要找一个用户群体,关注了第一个商品却没有关注第二个商品。每一个后果集都能够用bitmap数组来表白,数组之间做交差并集效率是十分高的。预计算技术实际上是把准确去重和交差并集上计算是有很大益处的。但缺点也比拟显著,最大的缺点就是不灵便,同时残缺SQL表达能力也比拟弱。另一种是属于MPP分布式数据库技术,一些通过列存、分布式、索引形式提供更好的查问性能。

所以真正落地一套人群筛选计划时,个别不是只抉择一个计划。因为不论是预计算计划还是MPP计划都有一些实质的缺点。

那市场上哪些技术更适宜做存储和查问呢?

第一类技术,大家都比拟相熟的事务数据库。事务数据库是行存储,对单行数据写入存储效率是十分高的,用来做查问,做过滤统计,在千万级以上会发现耗费资源是十分大的。所以个别不会拿TP零碎间接做剖析操作。

第二类零碎,AP零碎,是咱们常见OLAP零碎。这一类零碎针对大规模数据扫描场景做了优化,包含利用分布式技术,列存技术,压缩技术、索引的技术等等。这类技术查的都很快,但实质缺点是大部分零碎更新上做的不太敌对,因为数据查的快,所以数据该紧凑紧凑,该压缩压缩,所以在更新能力上弱一些。还有一类零碎,在大数据分析也常见,咱们把它叫Serving零碎,反对在线业务的一类零碎,这类零碎查的是足够快,但就义的其实是查问的灵活性。比方,文档数据库、KeyValue零碎查问形式有很大的局限,只能依照它的key去查问。这样灵活性缩小了,然而性能上有限放大,因为能够横向扩大,因为key相对来说拜访效率是最高的,而且更新效率也十分高,依照key更新,能够替换整条记录。咱们过来就不得不针对不同场景,把数据拆分到TP、AP、Serving,数据在几个零碎之间来回传递。让咱们对整个零碎的依赖度变的更高,只有数据有一次依赖,就会产生一次数据不统一,产生数据不统一就意味着数据的修改,数据的开发成本变的更高。所以大家都会在很多畛域做翻新,第一类翻新是在TP和AP畛域里做一个混合负载能力。尝试通过一个技术把这两个场景解决掉。有反对事务,又能反对剖析,也心愿将来有一天这个零碎真正很好的落地。这类零碎也有肯定的局限,要反对事务操作,各种分布式锁开销还是必不可少的。这类零碎因为具备了一些能力,所以在整个并发和性能上,开销是比拟大的,所以有肯定的性能瓶颈。

在下图左侧局部也是能够做一些翻新的,左侧的翻新会发现最大的问题是不反对事务。把事务能力弱化,不须要那么多事务,心愿查的足够快,更新的足够快。所以这个中央是有可能做技术创新,这个技术既具备很好的灵便的剖析能力,也具备很好的数据写入能力,有具备残缺的SQL表达能力。所以左侧的交加局部的技术,很适宜方才提到的三点技术要求。这就是明天要分享的产品Hologres。

Hologres=向量化SQL引擎 + 灵便的多维分析+高吞吐实时更新

Hologres,一站式实时数仓,提供实时剖析(OLAP)与在线服务(点查)两种能力,与MaxCompute无缝买通,实现一套架构,多种负载(OLAP、在线服务、交互式剖析)共存,缩小数据孤岛,防止数据割裂,简化链路,晋升用户体验。

对立存储

一份数据反对多种负载 (OLAP、在线服务、MaxCompute交互式剖析),缩小数据割裂

数据无孤岛,无频繁数据导入导出,进步数据开发效率、简化链路

对立接口

接口兼容开源Postgres协定,反对支流开发和BI工具,无需应用层重写,生态凋谢
对立用SQL形容多种场景,进步数据利用开发效率
对立数据模型,通过“表”来形容数仓模型,语义统一

实时离线一体

反对实时写入、实时更新、写入即可查,原生集成Flink
与MaxCompute存储无缝买通,通明减速,无需数据挪动,反对交互式剖析能力,反对实时数据关联历史数据

高性能

OLAP场景性能好于Clickhouse、Impala、Presto,反对亚秒级响应与高QPS
在线服务(点查)场景性能好于HBase,点查反对100K+QPS

Hologres:一站式实时数仓

Hologres为什么能反对高性能,高吞吐写入?

实际上没有神秘的中央,Hologres更多还是依赖于整个IT行业,有很多底层技术上的提高。比方,带宽变宽,提早变低。益处是之前必须依赖本地的操作,比方之前依赖本地磁盘,当初能够依赖网盘。其实Hologres底层的存储,分多正本存储,高牢靠存储,把这些负责状态治理的事件,都交给阿里云,底层是盘古存储引擎,自带多正本,自带压缩,自带缓存,自带高牢靠。这就会使整个计算节点的逻辑变的轻薄和简略,也让高牢靠更加简略。任何一个节点宕掉之后,能够很快从一个分布式的网盘里复原状态。会让计算层变的无状态,这是第一点。第二点是磁盘的利用,过来磁盘的转速有机械瓶颈。机械磁盘是按圈去转的,一秒钟多少转。所以咱们的IO场景都是面向扫描场景做了大量的优化。咱们心愿所有的数据都是以块为单位,进行更新、读写。所以在过来这种高更新场景,在整个数仓里很难实现。Hologres是采纳SSD设计,固态硬盘反对更好的随机读写能力。这让咱们设计存储架构的时能够抛开过来必须依赖于这种扫描场景,去设计整个存储的数据结构。Hologres能够行存也能够列存,别离适应不同的场景,同时也采纳log structured merge tree 的形式。反对高吞吐数据的写入和更新的场景。第三个是CPU多核化,CUP的主频曾经不会有实质的晋升。然而在多核化场景下,如果能够把一CPU外部多个核并行利用起来,就能把CPU资源充分发挥到极致。这就要求对操作系统的底层语言把握的要比拟好,Hologres应用C++实现的数仓。Hologres底层的算子都会用向量化形式重写,尽量施展多核化并行计算能力,吧计算力施展到极致。

从下图能够看出,咱们在网络上、存储上、计算上、硬件层面有很多改良,这些改良都充分发挥进去,可能做出一个不一样的成果的零碎。

人群圈选场景之前提到,既有预计算场景,又有MPP分布式计算场景。应用繁多某一个技术往往不太适宜,真正落地的时候,心愿既有预计算又有分布式计算,要把两个技术更好的整合在一起。比方维度过滤场景就很适宜用BITMAP,因为能够在BITMAP上做位图索引。如true和false的场景,购买级别、对什么产品关注等等,这些须要过滤的场景就适宜做位图索引。Hologres是反对位图索引的。

第二种是关系运算,关系运算是咱们提到的各种数据集之间的交差并,也非常适合位图计算。因为位图计算相当于是0和1之间,做很多与或差的操作,而且是并行操作,效率也是十分高的。

准确去重是BITMAP天生就具备的能力,因为位图在构建时,就通过下标位,就惟一确定了ID。通过不同下标位之间下面一的值的简略累加,就能够很快计算出准确去重的值是多少。这简直是把一个O(N)的问题变成O(1)的场景,成果也非常明显。所以在做人群圈选场景外面,预计算是很重要的技术。Hologres反对RoaringBitmap数据类型,高效率实现Bitmap的穿插并计算。

上文提到预计算是灵活性有余,须要通过分布式计算把计算力施展进去,就用到了Hologres的向量化执行引擎。对MaxCompute数据表面间接减速,包含MaxCompute数据同步到Hologres里,是会比MaxCompute同步到其它数据源性能进步10倍已上。

典型架构图

典型架构图如下,数据源根本是通过埋点数据,通过消息中间件kafka,第一件工夫投递到Flink,做一次轻量级数据加工,包含数据治理的修改,数据轻度汇总,数据维度拉宽。其中维度关联是一个很重要的场景,真正的埋点数据都是记录某些ID,这些ID都要转换成有属性意义的维度信息。第一件事就是做维度拉宽,这是就能够应用Hologres的行存表,维度关联时,根本是通过主键去关联的,应用Hologres的行存表,能够存几亿几十亿的维度信息。这些信息能够实时的被更新。加工的后果集会写到kafka外面,因为并不是一次加工,可能是加工几个循环。通过kafka做音讯驱动的形式,在Flink外面做几次加工,加工的后果基本上双写的场景会比拟多,一部分实时写入Hologres,另一部分以批量形式写到MaxCompute外面。离线数仓到实时数仓是一个很好的数据修改的场景,数据是肯定会被修改的,所以会有大量通过离线数仓对实时数仓进行修改的场景,包含标签加工也是典型的离线数仓来补充实时数仓的场景。所以一些行为是须要通过离线数仓加工好之后,把数据同步到实时数仓里。但有另外一些属性,是跟当下决策有关系的。这些是能够间接写到实时数仓Hologres里。所以能够把标签分为离线和实时两局部,实时写到Hologres,离线通过MaxCompute加工后同步到Hologres。

在对外提供数据服务是,有几种形式。倡议的形式是,对外提供服务时,加一个网关,网关服务外面会做很多限流、熔断等等,这也是能进步数据服务稳定性的一个很好的帮忙。如果是对内应用交互式剖析的长治,能够间接通过JDBC的形式连贯Hologres,如果是一个在线利用,倡议通过API网关连贯到Hologres。

数据结构层

离线数仓加工两张表,一个是用户根底属性表,记录一些用户属性,性别城市年龄等。一个是交易明细表,记录某个人在某一天针对某个商品买过多少,看过多少,珍藏多少等。这些通过离线数仓加工好后,数据导入Hologres。在通过配置把表列形容信息以人类可读的形式形容进去,再配置相干属性标签。把标签上线后,广告主会通过交互界面进行配置筛选。这种筛选背地都是翻译成各种SQL语句,其实就是个各种SQL表达式。真正把查问下发到底层引擎。那下发时底层引擎该如何建表呢?

宽表模式

•每行形容一个用户的标签组合,每个key是一列,每一行对应value。

•列不倡议超过300列,列多会升高实时写入的性能。分为热点标签和非热点标签

•热点标签独立为列,具备明确的数据类型,能够针对性设计索引,对查问敌对

•非热点标签,通过数组类型和JSON反对,适宜动静更新,但索引不是最优,可扩展性更好

•适应场景:维度属性数量较低;实时写入频繁;更新以人的单位

•劣势:开发简略疾速上线

•计划形容:

用户数据:例如user_tags表,宽表

行为数据:例如shop_behavior表,事实表

更新时,能够实时、批量更新不同的列

案例

-------------------- 用户标签维度表 ---------------------
begin;
--3个热点标签字段(text、integer、boolean类型),2个扩大标签字段(text[]类型和JSON类型)
create table user_tags
(
  user_id text not null primary key,
  city_id text,
  consume_level integer,
  marriaged boolean,
  tag_array text[],
  tag_json json
);
call set_table_property('user_tags', 'orientation', 'column');
-- 散布列
call set_table_property('user_tags', 'distribution_key', 'user_id');
-- text类型设置bitmap索引
call set_table_property('user_tags', 'bitmap_columns', 'city_id,tag_array');
-- 热点标签,这是字典编码
call set_table_property('user_tags', 'dictionary_encoding_columns', ‘city_id:auto’);
commit;
-------------------- 用户行为事实表 ---------------------
begin;
create table shop_behavior
(
  user_id text not null,
  shop_id text not null,
  pv_cnt integer,
  trd_amt integer,
  ds integer not null
);
call set_table_property('shop_behavior', 'orientation', 'column');
call set_table_property('shop_behavior', 'distribution_key', 'user_id');
--- 聚合键 对group by等运算更加敌对
call set_table_property('shop_behavior', 'clustering_key', 'ds,shop_id');
Commit;

窄表模式

将user_tag表转为窄表,每一个标签一行记录,标签名为一列,标签值为一列。

数据类型均进化为字符串类型,适宜标签不固定,标签稠密,容许就义局部性能但进步标签定义的灵便度。反对几十到几十万不同标签规模。

•适应场景:维度属性数量高;更新以标签的单位

•劣势:开发简略疾速上线

案例

-------------------- 用户标签维度表 ---------------------
begin;
create table tag2.user_tags
(
  userid text not null,
  tag_key text,
  tag_value text,
  ds text
) partition by list(ds);

call set_table_property('tag2.user_tags', 'orientation', 'column’); 
-- 散布列
call set_table_property('tag2.user_tags', 'distribution_key', 'user_id');
call set_table_property('tag2.user_tags', 'bitmap_columns', 'tag_key,tag_value');
call set_table_property('tag2.user_tags', 'dictionary_encoding_columns', 'tag_key:auto,tag_value:auto');
commit;
   
--查问例子--                        
WITH 
f1 AS (
    SELECT userid 
    FROM tag2.user_tags
    WHERE ds = '20210101'
    AND   tag_key = 'tag_single'
    AND   tag_value = 'myname'
),
f2 AS (
    SELECT userid 
    FROM tag2.user_tags
    WHERE ds = '20210101'
    AND   tag_key = 'tag_date'
    AND   tag_value > '20210101'
),
f3 AS (
    SELECT userid 
    FROM tag2.user_tags
    WHERE ds = '20210101'
    AND   tag_key = 'tag_numeric'
    AND   to_number(tag_value, '99G999D9S') > 90
),
f4 AS (
    SELECT userid 
    FROM tag2.user_tags
    WHERE ds = '20210101'
    AND   tag_key = 'tag_multi'
    AND   tag_value IN ('HONOR', 'MI')
)
SELECT COUNT(DISTINCT userid)
FROM ((SELECT userid FROM f1 UNION SELECT userid FROM f2) INTERSECT (SELECT userid FROM f3 EXCEPT SELECT userid FROM f4)) crowd;

预计算模式(宽表、窄表均适宜)

对维度组合的人群固化为更优的数据结构bitmap

•适应场景:基数高,计算复杂度大,更新频率低场景

•劣势:查问性能高

计划形容:

因为roaringbitmap须要整数类型作为ID参数,因而减少usermapping表做用户逻辑ID与底层物理ID的映射。

案例

-------------------- 用户标签维度表 ---------------------
BEGIN;
CREATE TABLE tag3.user_tags (
    "tag_key" text,
    "tag_value" text,
    "userlist" roaringbitmap,
    ds text
) partition by list(ds);
CALL SET_TABLE_PROPERTY('tag3.user_tags', 'orientation', 'column');
CALL SET_TABLE_PROPERTY('tag3.user_tags', 'bitmap_columns', 'tag_key,tag_value');
CALL SET_TABLE_PROPERTY('tag3.user_tags', 'dictionary_encoding_columns', 'tag_key:auto,tag_value:auto');
COMMIT;

begin;
create table tag3.usermapping
(
    userid_int serial,
    userid text
);
commit;

--构建RoaringBitmap--
INSERT INTO tag3. user_tags SELECT tag_key ,tag_value ,rb_build(array_agg(user_id::INT)) FROM tag2.user_tags GROUP BY tag_key ,tag_value 

--查问例子--
SELECT Rb_cardinality(Rb_and(Rb_or(t1.r, t2.r), Rb_andnot(t3.r, t4.r)))
FROM 
       (
              SELECT Rb_and_agg(userlist) AS r
              FROM   tag3.user_tags
              WHERE  ds = '20210101'
              AND    tag_key = 'tag_single'
              AND    tag_value = 'myname' ) AS t1,
       (
              SELECT rb_and_agg(userlist) AS r
              FROM   tag3.user_tags
              WHERE  ds = '20210101'
              AND    tag_key = 'tag_date'
              AND    tag_value > '20210101' ) AS t2,
       (
              SELECT rb_and_agg(userlist) AS r
              FROM   tag3.user_tags
              WHERE  ds = '20210101'
              AND    tag_key = 'tag_numeric'
              AND    to_number(tag_value, '99G999D9S') > 90 ) AS t3,
       (
              SELECT rb_and_agg(userlist) AS r
              FROM   tag3.user_tags
              WHERE  ds = '20210101'
              AND    tag_key = 'tag_multi'
              AND    tag_value IN ('HONOR',
                                   'MI') ) AS t4

用户画像与圈定的一些教训

•标签分为主画像和扩大画像多张表,辨别高频拜访和低频拜访

•标签分为实时(Flink)更新和离线(MaxCompute)更新两局部,两局部共享一张表,缩小运行时Join,Flink加工实时局部,MaxCompute加工离线局部,在Hologres中合并

•宽表模式简略,善于定性分析

•窄表模式灵便,计算量大,善于定量分析

•基于RoaringBitmap的预计算技术,用户体验最好,开发复杂度较高(比方bitmap分桶),SQL须要定制,适宜DMP等有封装能力的平台,善于UV

原文链接
本文为阿里云原创内容,未经容许不得转载。


推荐阅读
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文介绍了自动化测试专家Elfriede Dustin在2008年的文章中讨论了自动化测试项目失败的原因。同时,引用了IDT在2007年进行的一次软件自动化测试的研究调查结果,调查显示很多公司认为自动化测试很有用,但很少有公司成功实施。调查结果表明,缺乏资源是导致自动化测试失败的主要原因,其中37%的人认为缺乏时间。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • MySQL多表数据库操作方法及子查询详解
    本文详细介绍了MySQL数据库的多表操作方法,包括增删改和单表查询,同时还解释了子查询的概念和用法。文章通过示例和步骤说明了如何进行数据的插入、删除和更新操作,以及如何执行单表查询和使用聚合函数进行统计。对于需要对MySQL数据库进行操作的读者来说,本文是一个非常实用的参考资料。 ... [详细]
  • 本文总结和分析了JDK核心源码(2)中lang包下的基础知识,包括常用的对象类型包和异常类型包。在对象类型包中,介绍了Object类、String类、StringBuilder类、StringBuffer类和基本元素的包装类。在异常类型包中,介绍了Throwable类、Error类型和Exception类型。这些基础知识对于理解和使用JDK核心源码具有重要意义。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 【PPT 下载】这杯网红茶饮,到底赢在哪里?
    【PPT 下载】这杯网红茶饮,到底赢在哪里? ... [详细]
author-avatar
虎妞甜言蜜语说给上_235
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有