在上一篇文章中,我们介绍了如何下载安装部署SeaTunnel Zeta服务(3分钟部署SeaTunnel Zeta单节点Standalone模式环境),接下来我们介绍一下SeaTunnel支持的第一个同步场景:离线批量同步。顾名思意,离线批量同步需要用户定义好SeaTunnel JobConfig,选择批处理模式,作业启动后开始同步数据,当数据同步完成后作业完成退出。
下面以MySQL离线同步到StarRocks为例,介绍如何使用SeaTunnel进行离线同步作业的定义和运行。
SeaTunnel使用配置文件来定义作业,在这个示例中,作业的配置文件如下,文件保存路径~/seatunnel/apache-seatunnel-incubating-2.3.1/config/mysql_to_sr.config
#定义一些作业的运行参数,具体可以参考 http://seatunnel.apache.org/docs/2.3.1/concept/JobEnvConfig
env {
job.mode="BATCH" #作业的运行模式,BATCH=离线批同步,STREAMING=实时同步
job.name="SeaTunnel_Job"
checkpoint.interval=10000 #每10000ms进行一次checkpoint,后面会详细介绍checkpoint对JDBC Source和StarRocks Sink这两个连接器的影响
}
source {
Jdbc {
parallelism=5 # 并行度,这里是启动5个Source Task来并行的读取数据
partition_column="id" # 使用id字段来进行split的拆分,目前只支持数字类型的主键列,而且该列的值最好是离线的,自增id最佳
partition_num="20" # 拆分成20个split,这20个split会被分配给5个Source Task来处理
result_table_name="Table9210050164000"
query="SELECT `id`, `f_binary`, `f_blob`, `f_long_varbinary`, `f_longblob`, `f_tinyblob`, `f_varbinary`, `f_smallint`, `f_smallint_unsigned`, `f_mediumint`, `f_mediumint_unsigned`, `f_int`, `f_int_unsigned`, `f_integer`, `f_integer_unsigned`, `f_bigint`, `f_bigint_unsigned`, `f_numeric`, `f_decimal`, `f_float`, `f_double`, `f_double_precision`, `f_longtext`, `f_mediumtext`, `f_text`, `f_tinytext`, `f_varchar`, `f_date`, `f_datetime`, `f_timestamp` FROM `sr_test`.`test1`"
password="root@123"
driver="com.mysql.cj.jdbc.Driver"
user=root
url="jdbc:mysql://st01:3306/sr_test?enabledTLSProtocols=TLSv1.2&rewriteBatchedStatements=true"
}
}
transform {
# 在本次示例中我们不需要做任务的Transform操作,所以这里为空,也可以将transform整个元素删除
}
sink {
StarRocks {
batch_max_rows=10240 #
source_table_name="Table9210050164000"
table="test2"
database="sr_test"
base-url="jdbc:mysql://datasource01:9030"
password="root"
username="root"
nodeUrls=[
"datasource01:8030" #写入数据是通过StarRocks的Http接口
]
}
}
在这个作业定义文件中,我们通过env定义了作业的运行模式是BATCH离线批处理模式,同时定义了作业的名称是"SeaTunnel_Job"。checkpoint.interval参数用来定义该作业过程中多久进行一次checkpoint,那什么是checkpoint,以及checkpoint在Apache SeaTunnel中的作用是什么呢?
查看官方文档中对Apache SeaTunnel Zeta引擎checkpoint的介绍: http://seatunnel.apache.org/docs/2.3.1/seatunnel-engine/checkpoint-storage#introduction 发现checkpoint是用来使运行在Apache SeaTunnel Zeta中的作业能定期的将自己的状态以快照的形式保存下来,当任务意外失败时,可以从最近一次保存的快照中恢复作业,以实现任务的失败恢复,断点续传等功能。其实checkpoint的核心是分布式快照算法:Chandy-Lamport 算法,是广泛应用在分布式系统,更多是分布式计算系统中的一种容错处理理论基础。这里不详细介绍Chandy-Lamport 算法,接下来我们重点说明在本示例中checkpoint对这个同步任务的影响。
Apache SeaTunnel Zeta引擎在作业启动时会启动一个叫CheckpointManager的线程,用来管理这个作业的checkpoint。SeaTunnel Connector API提供了一套checkpoint的API,用于在引擎触发checkpoint时通知具体的Connector进行相应的处理。SeaTunnel的Source和Sink连接器都是基于SeaTunnel Connector API开发的,只是不同的连接器对checkpoint API的实现细节不同,所以能实现的功能也不同。
2.1.1 checkpoint对JDBC Source的影响
在本示例中我们通过JDBC Source连接器的官方文档http://seatunnel.apache.org/docs/2.3.1/connector-v2/source/Jdbc 可以发现如下内容:
这说明JDBC Source连接器实现了checkpoint相关的接口,通过源码我们可以得知,当checkpoint发生时,JDBC Source会将自己还未处理的split做为状态的快照发送给CheckpointManager进行持久化保存。这样当作业失败并恢复时,JDBC Source会从最近一次保存的快照中读取哪些split还未处理,然后接着处理这些split。
在该作业中通过partition_num=20,会将query参数中指定的sql语句的结果分成20个split进行处理,每个split会生成读取它负责的数据的sql,这个sql是由query中指定的sql再加上一些where过滤条件组成的。这20个split会被分配给5个Source Task进行处理,理想情况下,每个Source Task会分配到4个split。假设在一次checkpoint时每个Source Task都只剩下一个split没有处理,这个split的信息会被保存下来,如果这之后作业挂掉了,作业会自动进行恢复,恢复时每个Source Task都会获取到那个还未处理的split,并接着进行处理。如果作业不再报错,这些split都处理完成后,作业运行完成。如果作业还是报错(比如目标端StarRocks挂了,无法写入数据),最终作业会以失败状态结束。
断点续传:
如果在作业失败后,我们修复了问题,并且希望该作业接着之前的进度运行,只处理那些之前没有被处理过的split,可以使用 sh seatunnel.sh -r jobId来让作业ID为jobId的作业从断点中恢复。
回到主题,checkpoint.interval=10000对于从Mysql中读取数据意味着每过10s,SeaTunnel Zeta引擎就会触发一次checkpoint操作,然后JDBC Source Task会被要求将自己还未处理的split信息保存下来,这里需求注意的是,JDBC Source Task读取数据是以split为单位的,如果checkpoint触发时一个split中的数据正在被读取还未完全发送给下游的StarRocks,它会等到这个split的数据处理完成之后才会响应这次checkpoint操作。这里一定要注意,如果MySQL中的数据量比较大,一个split的数据需要很长的时候才能处理完成,可能会导致checkpoint超时。关于checkpoint的超时时长可以参数http://seatunnel.apache.org/docs/2.3.1/seatunnel-engine/checkpoint-storage, 默认是1分钟。
2.1.2 checkpoint对StarRocks Sink的影响
在Sink连接器的文档上,我们也能看到如下图中的标识:
这个标识代表该Sink连接器是否实现了精确处理一次的语义,如果该标识被选中,说明这个Sink连接器能保证发给它的数据它只会往目标端写入一次,不会漏掉导致目标端数据丢失 ,也不会重复往目标端写入。这一功能常见的实现方式是两阶段提交,支持事务的连接器一般会先开启事务进行数据的写入。当checkpoint发生时,将事务ID返回给CheckManager进行持久化,当作业中的所有Task都响应了CheckManager的checkpoint请求后,第一阶段完成。然后Apache SeaTunnel Zeta引擎会调用AggregateCommit的方法让Sink对其事务进行提交,这个过程被称为第二阶段,第二阶段完成后该次checkpoint完成。如果第二阶段提交失败,作业会失败,然后自动恢复,恢复后会再次从第二阶段开始,要求对事务进行提交,直到该事务提交完成,如果事务一直失败,作业也将失败。
并不是只有实现了exactly-once特性的Sink连接器才能保证目标端的数据不丢失不重复,如果目标端的数据库支持以主键去重,那只要Sink连接器保证发送给它的数据至少往目标端写入一次,无论重复写入多少次,最终都不会导致目标端数据丢失或重复。在该示例中StarRocks Sink连接器即是使用了这种方式,StarRocks Sink连接器会将收到的数据先缓存在内存中,当缓存的行数达到batch_max_rows设置的10240行,就会发起一次写入请求,将数据写入到StarRocks中。如果MySQL中的数据量很小,达不到10240行,那就会在checkpoint触发时进行StarRocks的写入。
我们使用Apache SeaTunnel Zeta引擎来运行该作业
cd ~/seatunnel/apache-seatunnel-incubating-2.3.1
sh bin/seatunnel.sh --config config/mysql_to_sr.config
作业运行完成后可以看到如下信息,说明作业状态为FINISHED,读取20w行数据,写入StarRocks也是20w行数据,用时6s。
大家好,又见面了,我是全栈君。二叉树节点#pragmaonce #include<stdlib.h> template<classT>classBinaryTreeNode { public: Tdata; BinaryTreeNode<T>*leftchild; BinaryTreeNode<T>*rightchild; BinaryTreeNode():leftchild(NULL),rightchild(NULL){} BinaryTreeNode(Td):data(d),leftchild(NULL),rightchild(NULL){} };复制二叉树的全部操作:建树。销毁树,先序后序中序便利的递归和非递归方式层序遍历 #include"BinaryTreeNode.h" #include<queue> #include<stack> #include<iostream> usingnamespacestd; /* voidCreatePreOrder(Bina
Java中两种分页遍历的使用姿势 在日常开发中,分页遍历迭代的场景可以说非常普遍了,比如扫表,每次捞100条数据,然后遍历这100条数据,依次执行某个业务逻辑;这100条执行完毕之后,再加载下一百条数据,直到扫描完毕那么要实现上面这种分页迭代遍历的场景,我们可以怎么做呢本文将介绍两种使用姿势常规的使用方法借助Iterator的使用姿势<!--more-->1.数据查询模拟首先mock一个分页获取数据的逻辑,直接随机生成数据,并且控制最多返回三页publicstaticintcnt=0; privatestaticList<String>randStr(intstart,intsize){ ++cnt; if(cnt>3){ returnCollections.emptyList(); }elseif(cnt==3){ cnt=0; size-=2; } System.out.println("=======================starttogenrandList===================="); List&l
作者:MayankPrasad译:徐轶韬在InnoDB中,用户定义的表及其对应的索引数据存储在扩展名为.ibd的文件中。表空间有两种类型,常规(或共享)表空间和独立表空间文件。对于共享表空间而言,来自多个不同表及其对应索引的数据可以保存在单个.ibd文件中。而对于独立表空间,单个表的数据及其索引保存在一个.ibd文件中。这篇博客文章将详细讨论这些.ibd文件中的空间管理。.IBD文件这些文件通常位于数据目录中。让我们尝试创建一个表test.t1。CREATETABLEtest.t1(cINT)engine=InnoDB;$cd<PATH_TO_DATA_DIR>/test$ls t1.ibd上面是独立表空间文件,即与表t1相关的表和索引数据将驻留在此文件中。TABLESPACE独立表空间的名称与文件/表名称相同,即上面表t1的表空间名称为t1。如果它是使用名称my_tablespace创建的常规(或共享)表空间,则该表空间名称将是my_tablespace..表空间使用唯一的ID标识,称为表空间ID。PAGES表空间文件由固定大小的页组成。不同类型的页可用于不同目的。我们将
DirectnavigationinCRMWebUIUsethisurlforexample: https://:44354/sap(bD1lbiZjPTAwMSZkPW1pbg==)/bc/bsp/sap/crm_ui_start/default.htm?crm-object-type=BPFS&crm-object-action=B&crm-object-value=120&crm-object-keyname=PARTNER theoverviewpageofbusinesspartnerwithid120incurrentapplicationservercoulddirectlybeopened:HowdoesCRMWebUIframeworkknowwhichtargetUIviewshouldbeusedforrendering? IntheurltheCRMobjecttypeBPFSandactionB(display)isspecified,bothofwhichareusedfortargetUIviewresolvation.Inmyex
本文记录OfficeOpenXML(OOXML)的测量单位在OfficeOpenXML默认单位是dxa也就是像素点的20倍,如ISO216A4(210x297mm~8.3×11.7in)的大小可以使用下面代码表示在页面大小PagewidthPageheight和边距margin和缩进tabs使用<w:pgSzw:w="11906"w:h="16838"/>复制单位计算可以使用下面公式像素Points=dxa/20 英寸Inches=Points/72 厘米Centimeters=Inches*2.54复制在OpenXML因为dxa是像素点的20倍,所以也叫二十分之一点,另外这里说的像素点是Point而不是像素Pixel哦缩写如下Points:ptInches:inCentimeters:cm以A4为例Width=11906dxa=595.3point=8.27in=21cm复制Half-points用来表示字体大小的半点,一个点等于两个半点,如表示12pt可以这样写//runproperties <w:rPr> //24=
异常处理是编程中十分重要但也最容易被人忽视的语言特性,它为开发者提供了处理程序运行时错误的机制,对于程序设计来说正确的异常处理能够防止泄露程序自身细节给用户,给开发者提供完整的错误回溯堆栈,同时也能提高程序的健壮性。这篇文章我们来简单梳理一下Laravel中提供的异常处理能力,然后讲一些在开发中使用异常处理的实践,如何使用自定义异常、如何扩展Laravel的异常处理能力。注册异常Handler这里又要回到我们说过很多次的Kernel处理请求前的bootstrap阶段,在bootstrap阶段的Illuminate\Foundation\Bootstrap\HandleExceptions部分中Laravel设置了系统异常处理行为并注册了全局的异常处理器:classHandleExceptions { publicfunctionbootstrap(Application$app) { $this->app=$app; error_reporting(-1); set_error_handler([$this,'handleError']); set_ex
零、前言今天写了一个圆点数字控件,效果如下: 最主要是想借此讲一下关于ListView,或RecyclerView的复用问题。 本案例在图片选择中测试,有时间会把我的图形选择小项目写一下,现在先看这个小控件吧。 本控件绘图部分使用我的LogicCanvas绘图库:基础使用在此,喜欢的话可以到github上看看,顺便给个star 支持属性依次:大圆颜色,圆的高度(原生宽高无效),文字,是否选中,小圆颜色。 toly:z_Dot_BigColor="@color/cornsilk" toly:z_Dot_Height="@dimen/dp_56" toly:z_Dot_text="H" toly:z_Dot_isChecked="false" toly:z_Dot_SmallColor="@color/small_circle"复制效果图.gif一、绘制1.绘制思路:大圆+小圆+文字+状态控制成员变量/** *大圆高 */ privatefloatmBigHeight=dp2px(20);
我们在项目开发过程中,常常需要查看APILevel和sdk版本,来进行一些方法的调用,有时候还需知道对应发布的时间,可以来了解我们最低兼容到的版本是什么时候发布的。 在这里贴出来方便以后查看:https://developer.android.com/guide/topics/manifest/uses-sdk-element.htmlAndroidversionhistoryPlatformVersionAPILevelVERSION_CODEIssueDateAndroid1.01发条机器人2008-09Android1.12PetitFour花式小蛋糕2009-02Android1.53Cupcake纸杯蛋糕2009-04Android1.64Donut甜甜圈2009-09Android2.05Éclair松饼2009-10Android2.0.16Éclair松饼2009-10Android2.17Éclair松饼2009-10Android2.2-2.2.38Froyo冻酸奶2010-05Android2.3-2.3.29Gingerbread姜饼2010-12Android
功能描述DescribeDocProcessBuckets接口用于查询已经开通文档预览功能的Bucket。 请求请求示例GET/docbucket?pageNumber=1&pageSize=2HTTP/1.1 Host:ci.<Region>.myqcloud.com Date:<GMTDate> Authorization:<AuthString> Content-Length:<length> Content-Type:application/xml 复制 说明: Authorization:AuthString(详情请参见请求签名文档)。 请求头此接口仅使用公共请求头部,详情请参见公共请求头部文档。 请求体该请求的请求体为空。 请求参数 名称 描述 类型 是否必选 regions 地域信息,以“,”分隔字符串,支持All、ap-shanghai、ap-beijing string 否 bucketNames 存储桶名
作为一名开发者,你经历过最可怕的流量是怎样的呢?对京东的这群架构师而言,京东11.11大促无疑是一场巨大的流量考验。摆在擂台上的是2715亿元的成交额,而在擂台背后,是一场关乎亿级、十亿级、百亿级流量的巨大战场。每一个技术故障都可能引发成倍的损失,与商家的厮杀对比,大促背后的战场可能更加残酷。 12月5日,由京东智联云主办,CSDN承办的开发者技术沙龙在北京落地举办。本次沙龙以“京东11.11大促,亿级流量背后的战场”为主题,吸引到大批开发者参与。京东用户增长、物流架构、存储、AI等部门以及英特尔的资深技术专家,与参会者共同探讨并分享了在京东11.11大促的极限流量下,京东技术预案准备、应对措施、难点技巧以及最佳实践。 一、群全链路稳定性设计,京东大促的用户秘密 作为一家电商平台,京东的大促就是流量峰值的象征。京东零售用户增长与运营部数据团队负责人周默先对京东近五年的大促技术体系演变进行了梳理。 京东2015年容器化,以传统物理机扩容缩容来承载关键业务;2016年中间件改造,京东升级三大技术框架以及监控、存储、数据库等系统;2017年全链路压测,引入“捣乱的猴子”方法论,保证任何零机
服务架构 随便选一个服务,任何服务都可以,别告诉我具体是哪个:)。你可以找到一些处理传入的消息或请求的监听代码;你可以找到一些连接组件的代码,还有一些初始化并激活这个服务的代码;或许你还能找到一些能适当地配置服务的代码。有没有觉得我很厉害?实际上,你可以在服务里找到上面的所有代码,至少是大部分。 有许多工作都是重复性的、常见的。我们可以好好利用这一点。 如何使服务能够适应不同的配置,避免设置监听器、组件连接等重复性常规工作? 第一个办法(实际上也不是什么办法),就是为每一个服务重写所有的连接代码。很显然,这不是个好方法,因为重写的次数越多,就越可能产生一些缺陷。并且,对于维护来说,许多重复的代码产生的问题更为严重。在维护的时候,你不仅要确保每一个服务中的缺陷都已经得到修正,还要保证没有任何疏漏、所有的服务都已经同步更新。 另一个相对较合理的办法,就是创建一个共同任务库,所有的服务都通过API与库相连接。这样确实会有所帮助,但是为了充分利用库的功能,你仍然需要编写连接代码。 还有一个办法是利用继承创建一个超类,用超类实现共同的功能,然后让各个服务继承这个类。然而利用继承也有问题,因为服务
RequireJS提供了JS下模块化开发的充分条件。之前我自己也在多个项目中尝试模块化开发,但是由于没有类似RequireJS这样的框架,最后的效果都不是很理想。在RequireJS中,所有的JS都是模块,这就意味着即便我们要以JQueryMobile作为应用的基础框架,也必须先加载RequireJS,然后再将JQueryMobile作为一个模块来加载使用。因此,在应用了JQueryMobile的应用中,我们在index.html中,通常只会看见一个js引用。<scriptdata-main="js/app"src="js/require.js"></script>复制 在进入JQueryMobile的讨论之前,先了解一下RequireJs。 RequireJS主要包含以下3个要素: require.config define require require.config require.config的例子代码如下: require.config({ baseUrl:'js', paths:{ jq:'jquery-1.10.2
一.基础命令: nginx-sreload:重新加载nginx配置 nginx-sstop:强制停止nginx nginx-squit:优雅停止nginx nginx-t:修改配置之后【测试】配置是否正确 nginx:默认启动nginx 查看server所有端口监听情况:netstat-ntpl 重启nginx服务:servicenginxstart(先kill#pid关闭正在运行中的nginx进程) 二.端口登入登出配置: 1.安装httpd工具,生成对应密码文件: yum-yinstallhttpd 2.用httpd命令生成密码文件,-ccreate htpasswd-c/etc/nginx/passwdusername 3.在nginx配置文件新增配置: location^~/oms/site{ add_headerCache-Controlno-cache; auth_basic"inputyourusernameandpassword"; auth_basic_user_file/etc/nginx/conf.d/auth-conf
近来项目需要WebService验证授权,一般有两种解决方案: 1.通过通过SOAPHeader身份验证。 2.通过集成windows身份验证。 今天我就尝试了已第二种方式进行授权,首先发布WebService到IIS,然后选择身份验证,启用Windows身份验证,禁用匿名身份验证 发布好了WebServive就要在Client端调用了,我用的是VS2008,在client端项目引用中右键添加服务引用,输入地址修改命名空间确定 接下来就要写后台调用代码了: 尝试了多种授权,始终会报HTTP请求未经客户端身份验证方案“Anonymous”授权。从服务器收到的身份验证标头为“Negotiate,NTLM”。的错误,很无解啊! 想到是不是因为.net3.5通过添加服务引用(WCF引用)的方式和2.0WebService有兼容性问题呢?老老实实的以WS2005的方式添加WebService再试: 因为发布WebService的时候启用了Windows身份验证,所有在引用时会提示你舒服用户名和密码,输完了下面的页面才是真正的“添加Web引用”而不是“添加服务引用” 接下来后台代
在网上买了一块单片机系统板,芯片是IPA15W4K58S4. 点亮8个LED灯,发现P1端口的6脚和7脚不亮,换其它的端口,发现也有几个脚不亮。 查资料得知,这些脚是高阻态,要设置成准双向口或强推挽模式才行。 (n:用1端口就写1,用2端口就写2) 比如要把P1端口的6脚和7脚设置为准双向口模式: P1M0各脚全部设为0即0x00; P1M2各脚也全部设为0,即0x00; 我们要先定义一个设置子函数,然后在主函数中引用。 如果直接赋值的话,会出错,说重复定义。 voidset_port() { P1M0=0x00; P1M1=0x00; }复制 最后成功点亮8个LED灯
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。 grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到标准输出,不影响原文件内容。 grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。 1.命令格式: grep [option] pattern file 2.命令功能: 用于过滤/搜索的特定字符。可使用正则表达式能多种命令配合使用,使用上十分灵活。 3.命令参数: -a --text #不要忽略二进制的数据。 
本文转自:http://blog.csdn.net/nightelve/article/details/7957726/ 单像素边框CSS表格 这是一个很常用的表格样式。 源代码: table.gridtable{font-family:verdana,arial,sans-serif;font-size:11px;color:rgba(51,51,51,1);border-width:1px;border-color:rgba(102,102,102,1);border-collapse:collapse} table.gridtableth{border:1pxsolidrgba(102,102,102,1);padding:8px;background-color:rgba(222,222,222,1)} table.gridtabletd{border:1pxsolidrgba(102,102,102,1);padding:8px;background-color:rgba(255,255,255,1)} InfoHeader1InfoHeader2InfoHea
搜索1.湖泊计数搜索寻找与之相连的点并修改2.算可达到的地板数搜索与之相连的点并计数3.总共三种字符求总共被字符分成多少个区域4.给10个数,判断是否可分成两个上升的子序列深搜遍历所有情况再依次判断5.小球撞石头,撞到石头石头碎,不超过10次能否达到目标点搜索遍历所有情况6.老鼠按照顺序1-10依次吃奶酪拆分,判断1-22-3再把路径依次相加7.流星砸地找安全的地方广搜判断所有地点8.2*40-7的顺序移动列举所有的情况,dp9.给若干个数求能组成两组正常的数字的差的最小值暴力所有情况求最小值10.一排数每次相邻两个相加(杨辉三角)给定最后的一个数求字典序最小11.给5*5的方格,求组成六位数的不同整数的数量12.翻煎饼列数少,暴力列数的可能性 作者:kidgzz 出处:https://www.cnblogs.com/Kidgzz/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
数据源:1、约300名代理商(销售)在移动端CRM中产生的客户数据、以及此平台中其它渠道产生的客户数据2、经营分析平台相关数据3、公众号、网上商城、第三方在线教育平台等产生的数据 机构介绍: 产品为单次消费制(有复训收费制度,但复训发生周期较长),不是按不同时间周期续费制的产品 常规分析:一、产品偏好1)分析角度:同一产品在不同地区的受欢迎程度(分地域各产品成交情况)2)在产品推荐、课程排期时有针对性的进行倾斜,推荐不同入口课程,再根据用户成交习惯分析引导后续消费 二、渠道分析 1)分析角度:不同渠道客户数量、成交总额等维度进行分析 2)目的:在不同时期不同渠道扮演的角色不同,需要根据具体情况进行渠道倾斜 3)应用一:在课程推广初期,可通过较高的分成来激励特定渠道,形成基础客户群,拉动新客; 4)应用二:产品受欢迎程度已比较乐观,那么就需要侧重培养自有低成本渠道,减少分成提高利润率,着重自有新客来源较多的渠道 5)应用三:新客较为理想,渠道较为优质,则需要考虑提高单客消费量,丰富产品线,增加消费选择,提升整体业绩 三、重要客户分析 1)一般存在代理商模式的培训机构,代理商本身可视为消费