- 博客(576)
- 资源 (102)
- 收藏
- 关注
原创 Spark Structured Streaming 分流或双写多表 / 多数据源(Multi Sinks / Writes)
在 Spark Structured Streaming 中,我们有时候需要将最后的处理结果分流或双写到多张表或多个数据源(Multi Sinks / Writes),一个典型的例子是:在 CDC 数据入湖场景里,一个 Kafka Topic 上存放着整库或多张表的 CDC 消息,使用 Spark 从 Kafka 中摄取这些消息后,需要根据消息中提供的数据库名和数据表名对 CDC 消息分流,然后写到数据湖上对应的 ODS 表中,这就是一种典型的“数据分流”场景。在 Spark Structured Stre
2024-04-28 10:24:42 1569
原创 Maven 构建 Flink 应用程序的最佳实践(根除各种类冲突/类加载问题)
作为开发者,在构建 Flink 应用程序时的体验真是一言难尽,想必大家都曾遇到过各种 ClassNotFoundException、NoSuchMethodError 以及 Could not find any factory for identifier kafka/jdbc/hive/hudi that implements org.apache.flink.table.factories.DynamicTableFactory in the classpath 这样的错误。坦率地说,Flink 的应用
2024-04-27 09:43:25 2279
原创 Flink CDC / Kafka Connect 自动转换 Debezium 的 DataTime / Timpstamp 时间格式
不管是用 Flink CDC 还是 Kafka Connect (Debezium Connector),在实时获取数据库的 CDC 数据并以 Json 格式写入 Kafak 中时,都会遇到 DataTime / Timpstamp 类型的转换问题,即:原始数据库中的 DataTime / Timpstamp 的字面量是 2021-12-14 00:00:00 这种形式,但是,转换为 Json 后就变成了 1639411200000 (带毫秒位的 epoch 时间),这带来的问题是:下游表基于 Json 数
2024-04-26 11:02:54 709
原创 Flink: Could not find any factory for identifier kafka/jdbc/hive implements DynamicTableFactory 根治方法
运行 Flink 应用或执行 Flink SQL 时会经常遇到下面的错误:org.apache.flink.table.api.ValidationException: Could not find any factory for identifier kafka jdbc hive hudi mysql-cdc that implements ‘org.apache.flink.table.factories.DynamicTableFactory’ in the classpath.
2024-04-25 09:59:27 1276
原创 Maven 安装第三方、非公共 Jar 包实现自动化构建
有时候,我们的程序可能需要使用到非官方的第三方 Jar 包,这些 Jar 包无法从 Public Maven Repo 中获得,但为了不影响自动化的构建流程,我们需要把这种 Jar 安装到构建服务器的本地 Maven Repository 中,以便整个项目的构建和部署依然能自动完成,而不必关系这些第三方 Jar 包如何部署与安置。本文我们就介绍一下具体操作。
2024-04-24 11:11:54 904
原创 Flink CDC:使用 Flink SQL 将多表写入一个 Kafka Topic 以及 Flink 作业数量的测试
本测试要验证两个问题:Flink CDC 能否将多张表的 CDC 数据 (debezium-json 格式)写入到同一个 Kafka Topic 中?验证使用 Flink SQL 方式将多表同时写入 Kafka 时,Flink 的作业数量,首先,准备好用 Flink SQL 实现的将两张表同步到一个 Kafka Topic 中的代码
2024-04-17 13:27:02 648
原创 Flink 报错 ClassNotFoundException: org.apache.kafka.connect.source.SourceRecord 解决方法
在使用 Flink CDC 的 API 编写整库、多表接入 Kafka 的程序时,遇到题目所述的报错。如果是自己编写的程序,可在 IDE 中直接查找该类是否在项目的依赖声明中;如果是部署的第三方应用,可以使用如下命令确认报错的类是否在所有依赖包中都不存在
2024-04-17 10:52:39 737
原创 Flink CDC 的 debezium-json 格式和 debezium 原生格式是一回事吗?
这是一个很容易混淆和误解的问题,值得拿出来讨论对比一下。我们知道 Debezium 是专门用于捕获 CDC 数据的开源框架,它对接了多种数据库,同时也定义了自己的 CDC 数据交换格式,也就是常说的 `debezium` 格式。而Flink CDC 复用了 Debezium 的部分功能,也就是说:Debezium 是 Flink CDC 的底层采集工具,Flink CDC 的工程依赖会用使用到 Debezium 的 Jar 包,然后 Flink CDC 在 Debezium 基础之上,封装了额外的功能,
2024-04-16 14:33:11 2035 2
原创 如何连通私有子网中的 MSK / Kafka 集群?
MSK 集群通常都是建在私有子网中的,这给本地访问带来了很多麻烦,特别是需要在本地使用 Kafka GUI 客户端管理和读写 MSK 数据的时候。本文会给出一套解决方案。我们这里讨论的问题有一点特殊性,那就是:由于 MSK 是托管服务,它的 Broker 主机名虽然映射了一个私有的 IP 地址,但是不能通过 SSH 登录的,这是比较特殊的一个地方,另一个地方是:Kafka 集群基本都是三个以上的 Broker,它的连接地址往往是三台以上的主机+端口号,这是另一个比较特殊的地方
2024-04-16 13:28:18 788 2
原创 Flink SQL:debezium-json 格式的表一定是数据库的 CDC 数据吗?
debezium-json 格式有一种非常典型的应用场景,就是:上游(Source)是一张使用 Flink CDC 接入的关系数据库中的表,下游(Sink)是一张创建在 Kafka 上的表,这张表的 format 往往会定义为 debezium-json,以便 Flink 能获得全面的 CDC 信息用于流上的实时处理,这种场景我们在 《Flink CDC 与 Kafka 集成:Snapshot 还是 Changelog?Upsert Kafka 还是 Kafka?》 一文的 ”测试组合(1):connect
2024-04-15 13:23:03 798
原创 Maven 项目 JDK 8、JDK 17 多版本 Java 编译依赖最佳实践
最近几年,整个 Java 生态圈正在经历并将长期出于从 JDK 8 到 JDK 17 或更高版本的升级换代中,较为典型是:以 Spring 为代表的 Web 应用开发框架大多已经升级到了 JDK 17,而在大数据生态圈,Flink、Spark 还在使用 JDK 8,对于那些多模块的 Maven 项目,会出现不同的 Module 使用不同版本的 JDK 问题,这给构建这类项目造成了一些困难,本文简单梳理一下这一问题的解决方法,给出最佳实践。
2024-04-15 11:13:31 1855
原创 Flink:流式 Join 类型 / 分类 盘点
在Flink中,实现流之间连接的操作可以分为两类。第一类是基于原生State状态存储的Connect算子操作,这种方式可以实现低延迟的数据连接和转换;第二类则是基于窗口的JOIN操作,这种方式又可以细分为window join和interval join两种,通过对数据进行时间窗口和滑动窗口的划分,实现不同粒度的数据关联和计算。Regular Join(常规 Join)Interval Join(时间区间 Join)Temporal Join (版本表 Join基于事件时间的 Temporal Join基于
2024-03-27 10:41:51 2329
原创 Flink:维表 Join 难点和技术方案汇总
目前看,Flink 的 “维表 Join” 主要就三种实现方式,叫法可能会有细微差别,以下是我是用更直白的语言总结的称谓:直连外部数据库进行关联;将维表加载到内存中关联;基于维表变更日志的关联。这些 Join 方案具体会使用到 Flink 的 Lookup Join、Temporal Join 等相关机制,所以在研究维表 Join 方案前,应先补齐这部分的知识,具体可参考本文末给出的本博客相关系列文章。
2024-03-26 09:25:39 1740
原创 一文聊透 Flink 的 Temporal Join
Flink的Temporal Join以及Temporal Table (时态表)关系密切,在知识结构上有点混乱,可能是历史原因造成的。本文希望把所有与 Temporal Join 相关的概念进行一次统一梳理,用更规范的知识结构把 Flink 的 Temporal Join 介绍清楚,包括:以 Temporal Table DDL 方式实现基于事件时间的 Temporal Join;以 Temporal Table DDL 方式实现基于处理时间的 Temporal Join;以 Temporal Table
2024-03-25 08:22:24 2132
原创 Flink:“Lookup Join”和“基于处理时间的 Temporal Join”的区别
在完整介绍了 “基于处理时间的 Temporal Join” 和 “Lookup Join” 之后,作为一个简单的盘点,也是回答最初接触这两种 Join 时的疑惑,我们来分析一下两种 Join 有何异同。相同之处:时效性都较高;时间维度上的关联准确性接近;不同之处:Lookup Join 是直连数据查询的,而 “基于处理时间的 Temporal Join” 是构建在 Flink 上的动态表,变更是靠 CDC 实时同步的。
2024-03-24 13:14:02 562
原创 Flink Temporal Join 系列 (4):用 Temporal Table Function 实现基于处理时间的关联
本文要演示的是:使用 Temporal Table Function 定义被关联表(维表),然后基于主动关联表(事实表)的“处理时间”去进行 Temporal Join(关联时间维度上对应版本的维表数据)。由于 Flink 在新版本中已经禁止使用 Temporal Table DDL 实现基于处理时间的 Temporal Join,所以通过 Temporal Table Function 实现基于处理时间的 Temporal Join 已经是唯一的手段了。该演示同样涉及三个要点:被关联的表(维表)是用 Te
2024-03-22 10:03:01 896
原创 Flink:Lookup Join 实现与示例代码
本文要演示的是:在流上关联一张外部表(例如 MySQL 数据库中的一张维表),用于丰富流上的数据,实际上,这正是最普遍的 ”维表 Join“ 的实现方式。通过这种方式和外部维表关联时,依然能关联到最新变化的维度数据,所以才说这是 ”维表 Join“。Lookup Join 与 《Flink Temporal Join 示例演示 (2):Temporal Table DDL + 处理时间》一文演示情形是很相似的,但不同之处在于:这里的维表是通过 JDBC 方式连接的,而文章中的 Temporal Join 方
2024-03-21 14:07:27 892
原创 Flink Temporal Join 系列 (3):用 Temporal Table Function 实现基于事件时间的关联
本文要演示的是:使用 Temporal Table Function 定义被关联表(维表),然后基于主动关联表(事实表)的“事件时间”去进行Temporal Join(关联时间维度上对应版本的维表数据)。该演示同样涉及三个要点:被关联的表(维表)是用 Temporal Table Function 形式定义的时态表;主动关联的表(事实表)需要定义:“事件时间”属性(但并不需要是一张版本表);Temporal Join 是使用 Temporal Table Function + LATERAL TABLE 关
2024-03-21 09:36:08 886
原创 使用 Flink + Faker Connector 生成测试数据压测 MySQL
使用 Flink 压测 MySQL 是一个不错的注意,或者,有时候我们需要在 MySQL 中生成一些可控的测试数据,这时使用 Flink 的 Faker Connector 就是会很简单。本文记录一下操作方法。
2024-03-20 13:31:35 949
原创 Flink Temporal Join 系列 (2):用 Temporal Table DDL 实现基于处理时间的关联
本文要演示的是:使用 Temporal Table DDL 定义被关联表(维表),然后基于主动关联表(事实表)的“处理时间”去进行Temporal Join(关联时间维度上对应版本的维表数据)。该演示涉及三个要点:被关联的表(维表)是用 Temporal Table DDL 形式定义,必须是一张时态表(版本表);主动关联的表(事实表)需要定义“处理时间”属性,但并不需要是一张时态表(版本表);Temporal Join 是使用 Temporal Table DDL + FOR SYSTEM_TIME AS
2024-03-20 09:49:35 667
原创 Flink:使用 Faker 和 DataGen 生成测试数据
DataGen 是开源 Flink 就内置的随机数据生成器;DataGen 生成的数据仅支持随机和序列值两种,且也并不是所有的数据类型都能支持随机或序列值,例如最见的一个需求:针对时间类型就不能生成指定区间内的单调递增的数值,相较而言,Faker 的功能要明显由于 DataGen,我们只需掌握 Faker 这一种数据生成器就足够了。
2024-03-19 10:56:33 992
原创 Flink Temporal Join 系列 (1):用 Temporal Table DDL 实现基于事件时间的关联
本文要演示的是:使用 Temporal Table DDL 定义被关联表(维表),然后基于主动关联表(事实表)的“事件时间”去进行Temporal Join(关联时间维度上对应版本的维表数据)。该演示涉及三个要点:被关联的表(维表)是用 Temporal Table DDL 形式定义,必须是一张时态表(版本表);主动关联的表(事实表)需要定义”事件时间“属性,但并不需要是一张时态表(版本表);Temporal Join 是使用 Temporal Table DDL + FOR SYSTEM_TIME AS
2024-03-19 08:57:41 613
原创 Linux:配置 rz 自动覆盖上传文件
Linux 上的 lz 和 rz 是两个很用的小工具。不少 Shell Client 工具都支持使用它们直接下载和上传文件。对 rz 来说,当一个文件已经存在服务器上时,再次上传同名文件时,为了避免覆盖掉现有文件,rz 选择给新上传的文件添加数字后缀,以作区分。这种处理方式虽然安全,但大多数情况下并不是用户希望的。
2024-03-18 12:58:59 928
原创 再谈 Flink 的“动态表”和“流表二象性”
本文再次去动态表和表流二象性做一些梳理。1.将流转换为动态表。2.在动态表上计算一个连续查询,生成一个新的动态表。3.生成的动态表被转换回流。我们会从实际代码层面把动态表的概念打通,核心问题就是:动态表的 DDL 定义了什么?持续查询又做了什么?动态表的 DDL 定义了三项核心要素:数据结构,数据源(connector),传输格式(format);从 ETL 的角度看,持续查询完成了最核心的 ETL 逻辑,从整个流式处理管道的角度看,是持续查询驱动了整个 Pipeline 运转,只有动态表的DDL,不会有任
2024-03-18 09:26:47 1105
原创 Flink:Temporal Table 的两种实现方式 Temporal Table DDL 和 Temporal Table Function
综合官方文档对 Temporal Joins 和 Temporal Table Function 两部分的描述可以梳理出以下重要结论:版本表的官方定义形式只有一种,就是 Temporal Table DDL,参考:声明版本表Temporal Table Function ( 时态表函数 ) 和 Temporal Table DDL 可以实现相同使用效果的时态表,可以说 Temporal Table Function ( 时态表函数 ) 相当于提供了 DDL 之外的另一种版本表的实现方式
2024-03-03 12:57:38 792
原创 Flink:Temporal Table Function(时态表函数)和 Temporal Join
我们知道,时态表(确切地说应该是版本表)提供了回溯历史的能力,也就是能读取一条记录过去某个时刻所对应的值。要想查询版本表在过去某个时刻对应的值,我们得在查询时把这个时间作为参数传递给版本表,但这个时间参数绝不会是一个 where 条件,它是另一个维度(时间维度)上的参数,那么用怎样的形式才能把这个时间参数合理地表达到查询中呢? Flink 使用了 UDF 的形式,主要思路就是:注册一个 UDF 来指代一张版本表,表名不能有参数,但函数可以有,这时把想访问版本表的目标时间点作为参数传给这个UDF,返回的就是当
2024-03-03 11:43:19 704
原创 SQL 术语:Join 中的 Build 和 Probe 是什么意思?
我们可能在一些介绍数据库 Join 档中看到 Build 和 Probe,分别代表着 Join 操作中的 右表 和 左表,为什么会有这样的称呼呢?原来它们都出自于一种叫 ”Hash Join“ 的 join 算法(常见的 Join 算法有:Hash Join、Loop Join、Merge Join)。先看一下名词解释:Hash Join:一种实现 Join 的算法,它通过在 Join 的一侧构建 Hash Table 并在另一侧不断匹配 Hash Table 来得到 Join 的结果。
2024-03-02 12:00:02 1263
原创 Flink:动态表 / 时态表 / 版本表 / 普通表 概念区别澄清
根据 [ 官方文档 ] 所述,在 Flink 中,时态表和动态表是一个概念,只是强调的侧重点不同。Flink 流上的表都是动态的,也就是一直在变化,所以被称为动态表,因为动态表都会随时间发生变化,所以也被叫作了 “时态表”。而根据能否 trace (追踪) 一张时态表的变化历史,时态表会细分成:版本表 和 普通表 两种,区别就是:版本表可以追溯历史,而普通表只保存当前最新状态的数据。Flink 官方文档中说:定义了主键约束和事件时间属性(通过 WATERMARK 关键字标识)的表就是版本表,并且举例说:数据
2024-03-01 12:56:50 822
原创 Flink CDC 提取记录变更时间作为事件时间和 Hudi 表的 precombine.field 以及1970-01-01 取值问题
CDC 数据中的记录变更时间标记着这条记录在数据库中执行对应操作(创建/更新/删除)的时间,可以说是天然的“事件时间”,特别是对于那些本身没有记录时间字段的表来说就更加合适了。Flink 官方文档 也建议在使用 CDC 的情况下,优先使用 CDC 中的这个时间字段,这个时间更加精准。与此同时,在定义 Hudi 表时,precombine.field 也是一个非常重要的配置,显然 CDC 数据中的记录变更时间是最合适的,没有之一。
2024-02-27 13:36:32 1021
原创 Flink SQL 中的流式概念:状态算子
传统的关系模型和 SQL 最开始都是为了批式处理而设计的,当把一个关系型查询应用到流式处理上时,在实现和转换的过程中,会有很多和批处理场景非常不同的地方,典型的例子就是:为了实现 SQL 的某些语义,Flink 必须在流上维持状态,典型的代表就是:连接、聚合 、去重 这些操作,它们都是“状态算子”,本质原因还是因为:流处理的表是无界的,流式查询是持续不停的,所以在流上维持状态是必须的。
2024-02-27 10:45:42 1427
原创 Flink:流上的“不确定性”(Non-Determinism)
先明确一下什么叫“确定性”:对于一个“操作”来说,如果每次给它的“输入”不变,操作输出的“结果”也不变,那么这个操作就是“确定性“的。通常,我们认为批处理的操作都是确定的,比如针对一张 clicks 表,假如表中的数据没有变化,无论我们执行多少次 SELECT * FROM clicks 操作,它的结果始终不变。但是,批处理操作并不一定总是“确定性”的
2024-02-24 12:56:40 1125
原创 使用 JMeter 生成测试数据对 MySQL 进行压力测试
数据库压测最主要的工作是:如何能简单地生成压测数据(Dummy Data),还要能控制好数据的取值范围,写脚本太麻烦,图形化工具收费还不通用,所以,我们选择使用老牌的压力测试工具:Apache JMeter,除了它内置了丰富的随机值生成方法外,还因为它是一个统一的压测平台,操作和配置都和其他类型的压测一致。本文以 Debezium 官方提供的 MySQL Docker镜像 中的 Inventory 数据库为示例介绍和演示压测步骤。
2024-02-22 12:43:09 2049 2
原创 快速构建 Debezium MySQL Example 数据库
Debezium 官方提供的 MySQL Example 数据库是一个很好的工具,它内置了一个名为 inventory 的数据库,且已经配置好了 binlog,在测试 CDC 方案时非常有用,同时,它又可以基于 Docker 快速部署,所以使用起来就更方便了。本文专门介绍一下这个数据库的使用的方法。本文操作预设本地已安装并配置好了 docker,如需先行安装 docker,请参考 《Apache Kafka 基于 S3 的数据导出、导入、备份、还原、迁移方案》一文第4节提供的 Shell 脚本。
2024-02-22 10:41:15 634
原创 问题:Spark SQL 读不到 Flink 写入 Hudi 表的新数据,打开新 Session 才可见
使用 Flink 向 Hudi 表中写入数据,使用 Spark SQL 的 Shell 查询 Hudi 表(使用的是 Hudi HMS Catalog 统一管理和同步 Hudi 表的元数据),结果在 Spark 中只能查询到打开 Shell 之前表中的数据,之后通过 Flink 写入的数据不可见,但重新打开一个新的 Spark SQL Shell,就可以看到了。
2024-02-21 10:51:03 1237 1
原创 工具网站:生成测试数据(Generate Dummy Data)
介绍一个能自动生成各种测试数据(包括 INSERT INTO 的 SQL 语句)的工具网站:https://generatedata.com/ 🢡 Quickstart 页面,可点选现成的字段, https://generatedata.com/generator 🢡 全自定义界面,自行设置字段名、类型、取值范围等该工具支持所有主流的数据格式,包括:CSV、JSON、MYSQL 的 INSERT INTO 语句以及主流编程语言的集合类型声明语句等。下图是定制数据的操作界面截图:
2024-02-21 08:57:27 408
原创 CDC 数据入湖方案:Flink CDC > Kafka > Hudi
本方案的技术链路为:使用 Flink CDC 将 MySQL 的 CDC 数据 (Json 格式)接入到 Kafka ,然后通过 Flink Hudi Connector 将摄取的 CDC 数据写入到 Hudi 表中。文本是本博客的 CDC 数据入湖系列方案中最为基础的一套堆栈,架构上也比较简单,适合作为 POC 快速搭建 CDC 实时处理链路。如果寻求更加适用于生产环境的解决方案,请参考
2024-02-20 11:27:20 840
原创 Flink Catalog 解读与同步 Hudi 表元数据的最佳实践
在当前的大数据格局中,Spark / Hive / Flink 是最为主流的 ETL 或 Streaming 引擎,元数据方面,Hive Metastore 可以视为事实上的 Data Catalog 标准,而在数据湖存储格式上,又有 Hudi、Iceberg 这类新晋的框架,在这种复杂的格局下,用户希望能它们之间能相互打通,以便能根据应用场景灵活地选择技术栈,同时又不会出现技术上的“隔离”,一个非常典型的例子是:当我们选择了 Hudi 作为数据湖的统一存储格式后,我们希望不管是 Flink 还是 Spar
2024-02-19 13:24:13 1335
原创 Flink 实时数仓关键技术解读:Upsert Kafka 和 动态表(Dynamic Table)
“动态表”的本质是什么?它本质上是一条流(Stream)以及在流上维持着的若干状态(State)!upsert-kafka connector 不同于 kafka connector 的主要地方就在于:通过 upsert-kafka 创建的表能自动同步源端数据表的变更,(Table 模式下)查询该表的结果总能和源表实时保持一致,对于初次接触 Flink 的开发者来说会感到“非常神奇”,因为 upsert-kafka 的数据表是建立在 Kafka 上的,Kafka 并不支持更新和删除操作,但 upsert-k
2024-02-19 11:17:31 1785
原创 Flink CDC 与 Kafka 集成:Snapshot 还是 Changelog?Upsert Kafka 还是 Kafka?
我们知道,尽管 Flink CDC 可以越过 Kafka,将关系型数据库中的数据表直接“映射”成数据湖上的一张表(例如 Hudi 等), 但从整体架构上考虑,维护一个 Kafka 集群作为数据接入的统一管道是非常必要的,这会带来很多收益。在 Flink CDC 之前,以 Debezium + Kafka Connect 为代表的技术组合都是将数据库的CDC数据先接入到 Kafka 中,然后再由后续的组件解析和处理。
2024-02-05 15:19:28 1409
原创 Flink 动态表 (Dynamic Table) 解读
根据过去在流上维持状态的编程经验,我们可以深刻地体会到:Dynamic Table 的本质其实是基于 changelog 数据流维持的一个流上的状态(State)!动态表是 Flink 能以 SQL 驱动和操纵流式处理的基础,也是 Flink 实现 ”批流一体“ 的一项内在的技术支撑。简单地说,它的思想就是:将一个”流“抽象成一张”无界”的数据表,这样就可以在上面施加 SQL 操作了。静态的关系表和数据流有可以类比的地方,这是能将两者映射在一起的理论基础,同时,它们之间也有难以弥合的差异,所以在某些方面
2024-02-05 14:44:40 2073
Big_Data_SMACK.pdf
2016-10-14
The.Art.of.Multiprocessor.Programming.Revised.Reprint
2014-02-06
win7下硬盘安装Linux(Fedora17,CentOS 6.4,Ubuntu 12.10,LinuxMint 13 64-bit)
2013-08-16
Packtpub.Hadoop.MapReduce.Cookbook.Jan.2013
2013-03-04
OpenSSH for Windows
2013-02-06
Professional Website Performance.pdf
2013-02-04
Red.Gate.SQL.Toolbelt.v1.8.2.238.Incl.Keygen
2013-01-14
Araxis.Merge.Professional.v2012.4260.x64-BEAN
2012-12-27
Apress.Pro.SQL.Server.2012.Practices.Nov.2012
2012-12-24
Professional JavaScript for Web Developers, 3rd Edition 附书中代码
2012-09-19
Head.First.HTML.and.CSS.2nd.Edition.Aug.2012
2012-09-11
Packtpub.Spring.Security.3.May.2010
2012-09-10
Pro Apache Log4j Second Edition
2012-09-06
PowerDesigner16.1 crack keygen 破解文件
2012-06-21
SecureCRT.v6.7.3.292(含注册码和破解补丁),
2012-06-13
SecureCRT.v6.7.3.292.x64(含注册码和破解补丁)
2012-06-13
Apache Solr 3.1 Cookbook
2012-04-24
Lucene in Action 2nd Edition
2012-04-24
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人