# 数据采集

[1. 客户端埋点](#22-客户端埋点)

[2. 服务端埋点](#23-服务端埋点)

[3. 工具导入（历史数据导入）](#24-工具导入（历史数据导入）)

## 1. 总体流程

神策分析提供了非常完备的数据接入方案，无论您的产品采用哪种技术架构，都可以非常容易的接入神策系统。

一般情况下，进行一次完整数据接入的流程如下：

1. 理解神策分析的基本概念，了解神策是干什么的，尤其是需要重点阅读[数据模型](https://54td.gitbook.io/shence/technical_guide/data_import/data_model)的说明。
2. 如果有对应的神策数据分析师协助，请确认已经拿到对应的事件设计方案，其中应当包含了所有的事件及属性的设计建议。
3. 如果是使用私有部署的方案，请和相关运维同事确认已经配置好正确的数据接入地址。如果对这一点不确定，请联系神策技术支持。
4. 测试数据和正式数据应该接入到不同的项目中，具体概念请参考[多项目](https://54td.gitbook.io/shence/technical_guide/data_import/multi_project)。
5. 根据事件设计和相关需求，按需要进行具体的接入工作，例如在客户端实施埋点或者导入历史数据，详情参考第二节。
6. 进行数据测试和验证，完成验证之后再上线到正式的环境。

以上流程仅供参考，如有任何疑问请联系您的神策咨询顾问。

## 2. 接入步骤

> **要点说明**

1. 无论使用哪种接入方式，建议先阅读[数据格式](https://54td.gitbook.io/shence/technical_guide/data_import/data_schema)，更好的理解神策数据接入的原理。
2. 强烈建议开发的时候使用 [DEBUG 模式](https://54td.gitbook.io/shence/technical_guide/data_import/debug_mode)，并在发布的时候关掉，具体方式请参考各个 SDK 的文档。
3. 经常使用[埋点管理](https://54td.gitbook.io/shence/technical_guide/data_import/track_manager)查看接入的详细情况。
4. 严格按照事件设计的定义来进行埋点，尤其注意不同来源（例如安卓/iOS，或者历史数据等）的事件、属性需要统一考虑，以免出现定义的冲突，尤其是数据类型的定义。例如以下是一些典型的**错误用法**：
   * Android 支付事件叫 pay\_order，iOS 的支付事件叫 PayOrder，这样会造成使用和理解上的困难。
   * Android 端的金额属性叫 money，类型是数字，而 iOS 端使用的是字符串类型，会导致数据无法导入。
5. 一个属性的类型由首次导入时的类型决定，后续导入只接受相同类型的输入， 类型不一致的输入数据会被整条拒绝。
6. 事件名称、属性名称、属性类型在一般情况下是不能修改的，请务必确认事件属性设计之后再进行数据接入。如果是测试阶段中有事件、属性的变更，可以使用项目重置功能来重新初始化测试环境：[重置项目](https://54td.gitbook.io/shence/technical_guide/multi_project#6-重置项目)。

### 2.1. 如何标识用户

所谓标识用户，是指选择一个合适的标识符（例如设备 ID 或者注册 ID）作为 **distinct\_id** 来发送数据到神策。是否选择了合适的 **distinct\_id** 对数据分析的准确性会有很大影响，因此，在进行任何数据接入之前，都应当先确认您的用户标识方式。神策分析提供了灵活、强大的用户标识能力，您可以根据自己的需求来选择合适的方案，具体请阅读文档[如何准确的标识用户](https://54td.gitbook.io/shence/technical_guide/data_import/user_identify)。如果您依然不确定如何进行用户标识，请联系神策的数据分析师。

### 2.2. 客户端埋点

> **如果您不需要从客户端接入数据，可以跳过此段**。

客户端接入目前有以下几类方案：

1. 直接使用神策客户端 SDK（[JavaScript](https://54td.gitbook.io/shence/technical_guide/detailed_guide/js_sdk) / [Android](https://54td.gitbook.io/shence/technical_guide/detailed_guide/android_sdk) / [iOS](https://54td.gitbook.io/shence/technical_guide/detailed_guide/ios_sdk)）。这个方案相对简单、易用，并且神策 SDK 提供了更多内置的功能（例如[渠道追踪](https://54td.gitbook.io/shence/technical_guide/track_installation)等）和可靠性保证（例如网络不好的情况下延迟发送）。同时神策的所有 SDK 都是完全开源的，不用担心有后门之类的安全问题。一般情况下，我们建议采用此方案。
2. 使用已有的业务 API，把埋点需要的数据同步传到业务服务器，然后在服务端再使用神策的服务端 SDK（例如 [Java](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/java_sdk)/[Python](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/python_sdk) 进行接入。这个方案本质上其实是服务端埋点，优点是对于业务统计可能会更加准确（因为和业务调用是同步的），安全性比较高（可以进行一定的客户端加密来增大伪造数据的难度），缺点是实施难度较大。我们一般建议对于关键的业务事件（例如购买、支付等）采用这种方案。
3. 使用自己的埋点 SDK。如果您已经使用了自己的埋点 SDK，并且已经比较完善了，那么可以继续使用此方案，然后和方案 2 一样通过服务端接入。
4. 如果您使用的是神策暂时不支持的客户端（例如 PC / Mac 软件），那么可以使用方案 2 或者方案 3，当然 也可以在客户端直接使用神策的[数据接入 API](https://54td.gitbook.io/shence/technical_guide/secondary_development/data_import_api) 进行接入。

### 2.3. 服务端埋点

> **如果您不需要从服务端接入数据，可以跳过此段**。

不管是客户端的埋点数据通过 API 发送给服务端之后，还是直接在服务端的已有业务逻辑里直接埋点，都属于服务端接入。服务端接入可以使用 [Java](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/java_sdk)/[Python](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/python_sdk)/[PHP](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/php_sdk) 等 SDK，每个 SDK 均有不同类型的发送方案（即 Consumer）可以选择，有两大类方案：

1. 使用直接发送数据的 Consumer（例如 Java 的 AsyncBatchConsumer），实时的发数据给神策的服务。优点是方便简单，缺点是在机器故障或者超大流量的极端情况下可能会丢失一小部分数据，并且可能对业务造成一定影响。如果数据量不大可以使用此方案。
2. 使用写入本地日志的 Consumer（例如 Java 的 LoggingConsumer），配合 LogAgent 进行导入。优点是因为有本地持久化，可靠性会更高，缺点是代码会稍微复杂，同时还需要自己负责本地日志的存储和删除等运维操作。建议在大数据量或者对数据准确性有高要求的时候使用此方案。

在一般情况下，我们都建议在服务的入口处（例如 MVC 的 Controller 层）进行埋点，这样既能获取到大部分埋点所需要的数据，又方便统一管理：如果有埋点额外需要的客户端数据（例如设备信息），可以通过 API 参数传入；对于埋点需要的业务数据（例如下单事件的优惠信息），则可以通过业务处理模块返回给 Controller 层。

### 2.4. 工具导入（历史数据导入）

> **如果您没有历史数据需要接入，可以跳过此段**。

对于已经存在的历史数据，无论是事件还是用户属性，我们都建议使用 [Java](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/java_sdk)/[Python](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/python_sdk)/[PHP](https://54td.gitbook.io/shence/technical_guide/detailed_guide_server/php_sdk) SDK 生成特定格式的数据，然后使用 [LogAgent](https://54td.gitbook.io/shence/technical_guide/import_tool/log_agent)（SaaS 版）、[BatchImporter](https://54td.gitbook.io/shence/technical_guide/import_tool/batch_importer)（小数据量/私有部署） 或者 [HDFSImporter](https://54td.gitbook.io/shence/technical_guide/import_tool/hdfs_importer)（大数据量/私有部署/集群版）等工具进行导入。也可以不使用 SDK，直接按照[数据格式](https://54td.gitbook.io/shence/technical_guide/data_import/data_schema)里的说明生成数据并导入。

一般情况下，历史数据即可以先导入，也可以等实时数据正式接入之后再导入，不影响最终的分析结果。但是如果使用了**login / track\_signup**，则请务必阅这里的[注意事项](https://54td.gitbook.io/shence/technical_guide/user_identify#224-服务端接入流程)，避免导入数据顺序不对导致的用户 ID 关联错误。

### 2.5. 用户属性的接入

> **用户属性（Profile）是可选的，如果您的业务里并不需要接入用户属性，可以跳过此段**。

事件（Event）总是在事件发生的时候进行 track，而用户属性（Profile）则不是那么固定，而是根据不同属性会有所不同，主要还是取决于具体属性的获取方式，一般来说主要有以下几种方式：

1. 伴随事件的发生：例如神策提供的客户端 SDK 会默认在用户首次访问的时候，设置用户的**首次访问时间**等属性。类似的，您也可以主动在用户首次购买的时候调用 profile\_set\_once 设置一个**首次购买时间**的属性。
2. 在属性修改时接入：即在某个用户属性被修改的时候（例如修改用户资料的接口）同时调用 profile\_set 系列接口。
3. 定时同步导入：即定时从业务数据库或者其它数据源中导出数据，然后用 [LogAgent](https://54td.gitbook.io/shence/technical_guide/import_tool/log_agent) / [BatchImporter](https://54td.gitbook.io/shence/technical_guide/import_tool/batch_importer) 导入神策系统。这里应该尽量用最后更新时间之类的字段来实现增量导入，否则每次全量导入可能会影响性能。
4. 实时同步导入：例如 MySQL 可以使用 [Applier](https://dev.mysql.com/tech-resources/articles/mysql-hadoop-applier.html) 来对数据的 Binlog 进行实时解析和同步，其它数据库也可以使用类似的工具。此方案的优点是不用修改已有业务代码，耦合性较低，但是需要根据具体数据库类型进行额外的开发。

由于用户属性的导入效率会低于事件，因此应该尽量避免非必要的 profile 操作，例如在数据没有变化的情况下重复更新某一个 profile。
