当金融科技遇上云原生蚂蚁金服是怎么做安全架构的

蚂蚁金服在过去十五年重塑支付改变生活,为全球超过十二亿人提供服务,这些背后离不开技术的支撑。在 2019 杭州云栖大会上,蚂蚁金服将十五年来的技术沉淀,以及面向未来的金融技术创新和参会者分享。我们将其中的优秀演讲整理成文并将陆续发布在“ 金融级分布式架构”公众号上,本文为其中一篇。本文作者:何征宇,gVisor 创始人,蚂蚁金服研究员 在云原生发展趋势之下,金融行业想要应用云原生技术,安全问题是一个非常大的拦路虎,而云原生社区对安全问题的重视程度远远不够。蚂蚁金服在落地云原生的时候,解决安全问题是重中之重,经过探索与实践,我们沉淀出了一套从底层硬件到软件、从系统到应用层的全链路金融级云原生安全架构。 金融行业最重要的就是信任,我们认为,安全所带来的信任,是一种无形的产品,支撑着所有金融业务。 顺应互联网时代发展,金融行业与机构也发生了很多的变化,包括 App、小程序等更多的访问渠道,更快的业务变化,更多的第三方供应商。但是,不管怎么变化,金融行业有一点始终不变,那就是 Zero Fault,对错误的零容忍,也就是对稳定性和安全性的极高要求。 这里,我还想澄清大家对金融行业的一个错误看法,就是,大家都说金融机构有很多遗留系统,很多技术是十几年前的,就认为金融机构的技术是落后的。但其实,金融行业一直是科技含量非常高的。前段时间有一部电影上映,叫《蜂鸟计划》,根据真实事件改编,讲一帮做高频交易的人,为了降低从堪萨斯到纽约交易所的时间,建造了一条上千英里直通两地的光纤,想尽办法去争取那最后一毫秒。所以,金融行业并不只有平庸保守的科技,它同样也在追逐最前沿最先进的技术,我们的使命就是要用科技来进一步武装金融行业,为金融科技注入更多的活力。 云原生架构其实代表一种新的生产力,金融行业肯定是需要云原生的,它为我们带来了节约成本和敏捷开发的能力,但是在它前面还需要加一个定语,就是安全的云原生架构,它里面不仅仅包含之前的相对简单的安全方案,而是一个从端到端的全链路可信的安全解决方案。包括明晰代码所有权,做到可信启动,对镜像的制作和发布收口,配合账号体系,明晰应用的所有权和访问权限;以及安全可独立部署的精细化隔离方案,将安全策略和实施集成在基础架构中,对软件开发和测试透明。 这里我们着重分享蚂蚁金服正在实践的几项云原生安全技术,包括云原生网络安全 Service Mesh,安全容器,以及机密计算。 云原生网络安全:SOFAMesh 当前,云原生里除了容器之外第二大技术其实就是 Service Mesh,从蚂蚁的实践来看,其实它对金融安全有非常高的帮助。它至少可以做到三点: 策略化高效流量控制,可以帮助运维迅速适应业务快速变化;全链路加密,保护端到端数据安全;流量劫持与分析,当发现异常流量与容器时,进行流量阻断。并且,这些工作对业务是透明的,不需要给业务开发增加负担,同时我们还可以对流量进行实时的语义分析等等,做比传统的防火墙更多的事情。 蚂蚁金服在对 Service Mesh 的探索中,推出了自己用 Golang 打造的 SOFAMesh,并且已经对外开源,希望和社区一起努力,让 Service Mesh 的理念和技术更加普及。 SOFAMesh 是基于 Istio 改进和扩展而来的 Service Mesh 大规模落地实践方案。在继承 Istio 强大功能和丰富特性的基础上,为满足大规模部署下的性能要求以及应对落地实践中的实际情况,所做的改进包括采用 Golang 编写的 SOFAMosn 取代  Envoy,极大降低了 Mesh 本身的开发难度,并做了一些创新性工作,例如合并Mixer到数据平面以解决性能瓶颈,增强 Pilot 以实现更灵活的服务发现机制,增加对 SOFARPC、Dubbo 的支持,等等。 更多详情可查看 SOFAMesh 的 GitHub 主页:https://github.com/sofastack/... 蚂蚁金服率先在生产环境中大规模落地 SOFAMesh,超过 10W+ 容器做到了 Mesh 化,平稳支撑了 618 大促,给我们带来了多协议支持、UDPA、平滑升级、安全等多方面的好处,并且对性能仅有轻微的影响,单跳 CPU 增加 5% 损耗,RT增加不到 0.2ms,甚至部分业务经过 Mesh 化改造将业务链路下沉,RT 反而下降 7%。 ...

October 15, 2019 · 2 min · jiezi

蚂蚁金服OceanBase挑战TPCC-测试流程解析

蚂蚁金服自研数据库 OceanBase 登顶 TPC-C 引起业内广泛关注,为了更清楚的展示其中的技术细节,我们特意邀请 OceanBase 核心研发人员对本次测试进行技术解读,共包括五篇: 1)TPC-C基准测试介绍2)OceanBase如何做TPC-C测试3)TPC-C基准测试之SQL优化4)TPC-C基准测试之数据库事务引擎的挑战5)TPC-C基准测试之存储优化 本文为第二篇,其它文章已同步发布,详情请在“蚂蚁金服科技”公众号查看。 众所周知,TPC 组织是当今国际数据库领域公认最权威的测试和评价组织,它成立的初衷就是构建最好的测试标准以及制定针对这些标准最优的审计和监测流程。数据库界的天皇巨星 Jim Gray 曾在 1985 年提出了针对事务处理能力的评价标准 DebitCredit,而 1988 年 TPC 组织成立伊始,就基于这个标准提出了 TPC 组织第一个针对 OLTP 应用的测试标准 TPC-A。但随着时代发展,TPC-A 已经慢慢无法完全体现真实应用场景,此时 TPC-C 肩负重任应运而生,接下来也一直是 TPC 组织最核心同时也是关系数据库领域最顶级的测试标准。TPC-C 标准比 TPC-A 更加复杂,压力负载模型是 16 位一线工业产业界学者一起参与制定,随着时间推移测试标准也一直在保持修订,所以其模拟大型在线商超的测试模型时至今日也仍不过时,越来越能找到和当前大型 B2C 电商网站的共通之处。 有机会挑战 TPC-C 测试相信是所有数据库内核开发人员的梦想,但 TPC-C 测试标准非常复杂,1992 年 7 月发布以来到现在已经是 v5.11.0 版本,仅 PDF 就 132 页,如果不是铁杆粉丝估计很少有人会认真通读完这个标准。这次 OceanBase 创造 TPC-C 记录引起了大家的广泛关注,但它也只是这个测试标准里体现跑分的一个评价项 MQTh(最大有效吞吐量),隐藏在跑分下面的是 TPC-C 标准对被测数据库无数细致入微的测试验证和评价项,而正是这些才让这个标准在关系数据库领域如此权威,同时也是国产数据库之前很难入场的一大原因。 由于这是国产数据库同时也是分布式数据库第一次冲击这个榜单,为了完成这次挑战,OceanBase 团队前后准备时间超过一年,仅审计认证过程就耗时约半年,除了数据库自身性能优化同时还有大量的稳定性、合规要求相关工作,6088w tpmC 其实也只是整个测试结果中一小个展示项而已。 前期准备作为基于 LSM-Tree、多副本 paxos 强一致的新型分布式关系数据库,如何进行 TPC-C 测试,有哪些注意事项,什么时候该做什么步骤等等诸多问题,在审计刚启动时我们无处咨询也没有任何可借鉴的资料。TPC-C 测试首先需要找到官方唯一认证的审计员来对测试进行审计监察,但面对 OceanBase 这样一个全新架构的关系数据库时,他们其实也有着诸多和我们类似的疑惑和问题,因此他们对这次 OceanBase 的审计也相当重视,全世界仅有的三个审计员这次就有两个参与到测试审计工作中。 ...

October 8, 2019 · 2 min · jiezi

MIT6824Lab1P3

Part III: Distributing MapReduce tasks要干什么?前面的都是串行执行MRTask, 这次我们要用多线程模拟分布式环境, 来进行分布式MR.具体的任务是: 完善schedule.go: schedule(): 从registerChan读取已注册worker, 它会返回一个包含worker的rpc地址的字符串.给每一个worker分配一系列任务等待所有Task完成后, 返回schedule()应该使用全部worker, 有一些worker可能在schedule() 执行时才启动.schedul()通过Worker.DoTask()让worker执行任务.前置条件因为设计到并发编程, 所以我们可能要用到: goroutinechannelgo的RPC库, 用来和Worker通信sync.WaitGroupGo的race detector.select语句, 用来检查超时我们还要了解如下文件: mapreduce/common_rpc.gomapreduce/master.gomapreduce/worker.go代码构思为每个worker分配若干个task这是作者最初的思路: 创建布尔数组追踪每个job是否完成对每个worker, 用goroutine调用call()来分配Task对于每个call(), 设定timeout, 如果timeout内返回true, 则标记该Task完成; 否则重新分配该Task给另一个worker.如果所有Task完成, 则break.注意: registerChan返回的是已注册的worker的RPC地址,不等y于空闲的worker!要自己管理这些worker! 这里笔者把问题想复杂了, 导致代码一团糟, 且出现很多多线程bug. 实验P3前提是分布式无差错环境, 不用考虑容错。 为每个task分配一个worker参考了这篇博客。一个重要的思路: 每个worker完成task后, 将其名字放入registerChan, 日后再用.一个小坑: 最后一个goroutine中把名字放入chan, 这时没人来取它了, 会导致阻塞。通过把: registerChan <- workerName // 阻塞, 会导致任务完成但goroutine阻塞不返回改为: // 最后一个task时会阻塞但是没问题, 主线程退出, 它也就结束了。go func(){ registerChan <- workerName }代码: RPCMethodName := "Worker.DoTask"var wg sync.WaitGroup// For each task, assign it to a worker.// Not for each worker , assign many tasks to it.for i := 0; i < ntasks; i++ { workerName := <-registerChan go func(TaskIndex int, waitG *sync.WaitGroup) { waitG.Add(1) defer waitG.Done() args := DoTaskArgs{ JobName: jobName, File: mapFiles[TaskIndex], Phase: phase, TaskNumber: TaskIndex, NumOtherPhase: nOther, } call(workerName, RPCMethodName, args, nil) // For the last task, the goroutine will block. But it will be killed while main exiting. go func() { registerChan <- workerName }() return }(i, &wg)}wg.Wait()可以通过测试. ...

October 2, 2019 · 1 min · jiezi

MIT6824Lab1

P1: 编写map()和reduce()P2: 完成word count程序P3: 分布式无差错环境P4: 分布式容错P5:完成一个倒排索引, 没写。

October 2, 2019 · 1 min · jiezi

MIT6824Lab1P1

Part I: Map/Reduce input and output添加代码: common_map.go: doMap()common_reduce.go: doReduce()完成后测试: cd "<project_position>/src/mapreduce"go test -run Sequential我们需要事先掌握如下: 保存读取json文件文件输入输出.defer语句, 用于释放资源.common_map.go: doMap()要干什么?doMap()管理一个Map Task.调用mapF()将输入文件的内容变成一个[]KeyValue.用划分函数将mapF()的输出划分到nReduce个中间文件.每个中间文件命由<JobName>-<mapTask>-<reduceTask>三部分组成.代码构思:创建nReduce个json文件, 将其句柄放入jsonArr这个数组中, 其类型为[][]KeyValue.读取文件将其内容转为String, 输入mapF()得到输出kvList.对于kvList中每个kv, 用index = ihash(kv.Key) % nReduce来将其加入数组jsonArr[index]中.把jsonArr每一个数组jsonArr[i]保存到文件jobName-mapTask-i中(调用reduceName(..)).中间文件的格式由自己设计, 只要doReduce()能够正常decode就好.实现:func doMap( jobName string, // the name of the MapReduce job mapTask int, // which map task this is inFile string, nReduce int, // the number of reduce task that will be run ("R" in the paper) mapF func(filename string, contents string) []KeyValue,) { contentsByte, err := ioutil.ReadFile(inFile) if err != nil { log.Fatal(err) } contents := string(contentsByte) kvList := mapF(inFile, contents) jsonArr := make([][]KeyValue, nReduce) for _, kv := range kvList { index := ihash(kv.Key) % nReduce // Key or Value ? jsonArr[index] = append(jsonArr[index], kv) } // Save as json file. for i := 0; i < nReduce; i++ { filename := reduceName(jobName, mapTask, i) file, err := os.Create(filename) if err != nil { log.Fatal(err) } enc := json.NewEncoder(file) ok := enc.Encode(&jsonArr[i]) if ok != nil { log.Fatal(ok) } file.Close() }}common_reduce.go: doReduce()要干什么?doReduce()管理一个reduce任务r.从每一个MapTask的ReduceTask编号为r的中间文件中(共nMap个), 读取kv对, 转为String.将kv对按照key排序.对每个不同的key调用reduceF(), 将输出结果写入磁盘调用sort包来排序, 教程. ...

October 2, 2019 · 2 min · jiezi

MIT6824Lab1P2

Part II: Single-worker word count就是自己编写mapF()和reduceF().关键是如何分割出Word, 这里的定义是: A word is any contiguous sequence of letters, as determined by unicode.IsLetter.下面这个分割方式可以通过测试: tmps := strings.FieldsFunc(contents, func(ch rune) bool { return !unicode.IsLetter(ch)})可通过测试. 笔者曾按空白分割字符串, 如何检查string是否全是letter来判断是否是字符,这样的做法会导致如下: "it's" // 应该是 "it", "s""however,"" // "however"等字符串被判断为不是word.

October 2, 2019 · 1 min · jiezi

MIT6824Lab1P4

概述这次我们要处理worker故障. master通过调用common_rpc.go: call()来分配任务.当超时发生, 该函数 返回false, 这时候master要把该任务重新分配给另一个worker.common_rpc.go: call()返回false不等于执行失败, worker可能执行得比较慢导致超时.这样可能导致, 实际上有多个worker在执行同一个task(对于master来说, 只有一个).此外, mapreduce通过GFS保证task的输出是完整的和原子的(要么全部文件都输出, 要么都不输出), 这个实验并没有实现这个保证, 之间简单地令worker crash.问题面对worker故障, 我们应该如何调整schedule()的代码? 当所有task都被完成了, schedule就结束, 那么如何跟踪每个task的状态? 有别于论文, 实验中可能出现的故障有(按阶段分类): 执行map阶段发现worker crash, 重新分配taskmap阶段结束, 中间输出已写入到本地disk, mapper不可访问, 但由于实验是多线程模拟分布式环境, 所有内容都是可见的, 这些中间结果也是可访问的.执行reduce任务出错, 重新分配该任务即可。reduce执行完毕, reducer出故障, 结果也是可访问的, 所以不予考虑.worker向disk输出结果(包括中间文件、job result)出错。这里没有GFS, 只是简单地让worker crash。所以也等价于执行task中出错。所以我们只需要考虑: task执行失败如何处理。 实现我们首先看test_test.go文件: func TestOneFailure(t *testing.T) { mr := setup() // Start 2 workers that fail after 10 tasks go RunWorker(mr.address, port("worker"+strconv.Itoa(0)), MapFunc, ReduceFunc, 10, nil) go RunWorker(mr.address, port("worker"+strconv.Itoa(1)), MapFunc, ReduceFunc, -1, nil) mr.Wait() check(t, mr.files) checkWorker(t, mr.stats) cleanup(mr)}func TestManyFailures(t *testing.T) { mr := setup() i := 0 done := false for !done { select { case done = <-mr.doneChannel: check(t, mr.files) cleanup(mr) break default: // Start 2 workers each sec. The workers fail after 10 tasks w := port("worker" + strconv.Itoa(i)) go RunWorker(mr.address, w, MapFunc, ReduceFunc, 10, nil) i++ w = port("worker" + strconv.Itoa(i)) go RunWorker(mr.address, w, MapFunc, ReduceFunc, 10, nil) i++ time.Sleep(1 * time.Second) } }}TestOneFailure() 使得worker0在10个rpc后dump掉, ...

October 2, 2019 · 4 min · jiezi

分布式-dble-用-jumpstringhash-替换-Mycat-一致性-hash-原因解析

作者:爱可生开源社区背景MyCat 对于字符串类型为分片字段的数据,有三种分片模式,分别是:模值 hash(求模法),jumpstringhash(跳跃法),一致性 hash(环割法)DBLE 对于 hash 算法选取方面,除了继承 MyCat 的模值 hash,并没有延续使用 MyCat 的一致性 hash,而是选取了另一种流行的算法 —— jumpstringhash。介绍下面对于环割法(一致性 hash)及跳跃法(jumpstringhash)的原理、特性及优缺点进行简单的介绍。 环割法(一致性 hash)环割法的原理如下: 初始化的时候生成分片数量X × 环割数量 N 的固定方式编号的字符串,例如 SHARD-1-NODE-1,并计算所有 X×N 个字符串的所有 hash 值。将所有计算出来的 hash 值放到一个排序的 Map 中,并将其中的所有元素进行排序。输入字符串的时候计算输入字符串的 hash 值,查看 hash 值介于哪两个元素之间,取小于 hash 值的那个元素对应的分片为数据的分片。特点缺点随机性强初始化耗时长,内存消耗较高,需要进行大量数据排序,分片消耗高跳跃法(jumpstringhash)跳跃法的原理如下: 根据公式: 将数据落在每一个节点的概率进行平均分配。 对于输入的字符串进行计算 hash 值,通过判断每次产生的伪随机值是否小于当前判定的节点 1/x,最终取捕获节点编号最大的作为数据的落点。在实际使用中使用倒数的方法从最大节点值进行反向判断,一旦当产生的伪随机值大于 x 则判定此节点 x 作为数据的落点。特点内存消耗小,均衡性高,计算量相对较小数据比较下面将通过测试对环割法和跳跃法的性能及均衡性进行对比,说明 DBLE 为何使用跳跃法代替了环割法。 数据源:现场数据 350595 条测试经过: 通过各自的测试方法执行对于测试数据的分片任务。测试方法:记录分片结果的方差;记录从开始分片至分片结束的时间;记录分片结果与平均数的最大差值。由于在求模法 PartitionByString 的方法中要求分片的数量是 1024 的因数,所以测试过程只能使用 2 的指数形式进行测试,并在 PartitionByString 方法进行测试的时候不对于 MAC 地址进行截断,取全量长度进行测试。测试结果: 使用不同方法时,方差随分片数量的情况变化表| 分片数量方差| 环割法1000片 | 环割法10000片 | 跳跃法 || ----- | ----- | ----- | ----- | | 4 | 4484780 | 812418 | 315703 || 8 | 601593 | 545599 | 315587 || 16 | 453694 | 131816 | 67018 || 32 | 213856 | 74360 | 86125 || 64 | 69313 | 46618 | 37939 || 128 | 24329 | 26415 | 25429 | ...

September 10, 2019 · 2 min · jiezi

从入门到放弃ZooKeeperZooKeeper入门

前言ZooKeeper是一个分布式服务协调框架,可以用来维护分布式配置信息、服务注册中心、实现分布式锁等。在Hbase、Hadoop、kafka等项目中都有广泛的应用。随着分布式、微服务的普及,ZooKeeper已经成为我们日常开发工作中无法绕过的一环,本文将从安装配置到最基础的使用入手,对其进行介绍。 安装部署下载在 http://mirror.bit.edu.cn/apache/zookeeper/stable/ 下载推荐的stable版本。可以直接下载编译好的bin文件。目前最新的stable版本是3.5.5 解压将下载的文件解压至工作目录,我的工作目录是/var/workspace/zookeeper tar -xzvf apache-zookeeper-3.5.5-bin.tar.gz -C /var/workspace/zookeeper配置 此时如果直接启动zookeeper是会失败的,提示找不到zoo.cfg文件。需要我们把conf目录中提供的zoo_sample.cfg示例配置文件,复制为一份zoo.cfg,zoo.cfg是默认的启动配置文件 cp ../conf/zoo_sample.cfg ../conf/zoo.cfg启动 默认启动,使用config/zoo.cfg配置文件在后台启动 前台启动,会将启动日志打印在终端。终端关闭后服务也关闭。 访问 使用zcCli.sh -server host:port 访问ZooKeeper服务器。不加-server参数时,默认使用127.0.0.1:2181 使用ZooKeeper使用类似资源文件目录的方式来管理节点,每个节点可以存储数据。ZooKeeper有四种不同类型的节点: PERSISTENT:持久化节点,除非手动删除,否则会永久保存PERSISTENT_SEQUENTIAL:持久化顺序节点,除非手动删除,否则会永久保存。默认会在用户设置的节点名称后,顺序的增加十位的数字字符串。如 test_0000000001EPHEMERAL:临时节点,在session结束后,临时节点会被自动删除。EPHEMERAL_SEQUENTIAL:临时顺序节点,在session结束后,临时节点会被自动删除。默认会在用户设置的节点名称后,顺序的增加十位的数字字符串。如 test_0000000001help使用zkCli.sh连接到服务端后,可以使用help展示常见命令的使用方式。 ls 列出某个路径下的节点 create 可以使用create {path} 创建节点。使用 create -s {path} 可以创建有序节点,后面添加十位递增的数字后缀。 使用 create -e 创建临时节点,当断开连接后,临时节点会被删除。 set/get ZooKeeper的节点可以存储数据,使用set 方法将数据存在节点中。使用get 方法,从节点中获取数据。 set -v {currentVersion} {path} {data} 节点的数据每次更新时,都会递增,如果要更新节点,请使用上面的命令修改,如果currentVersion不是最新版本时,则更新失败,类似乐观锁CAS。 delete 可以通过delete删除节点。 总结通过上面的学习,我们已经学会了ZooKeeper最基本的安装部署及使用方式。需要牢记: ZooKeeper的节点是类似文件系统的管理方式Zookeeper有四种节点类型,临时节点会在会话断开后自动删除,顺序节点后缀序号会自动递增set数据时,可以指定版本号,版本号与当前版本一致时才更新。这种乐观锁的更新方式,可以避免并发时数据被覆盖 本文作者:aloof_阅读原文 本文为云栖社区原创内容,未经允许不得转载。

September 9, 2019 · 1 min · jiezi

阿里云-ESSD-采用自研新一代存储网络协议打造超级高速

8月26日,阿里云透露,正投入自研数据存储“超级高速”,核心存储产品ESSD已率先采用这一最新的自研存储网络协议,并实现大规模商用,数据传输效率提高50%。 据了解,未来该协议还将继续演进,有望取代传统TCP网络协议。此前,谷歌、微软也曾先后发表论文试图突破瓶颈,但都未大规模应用。 随着AIoT时代的到来,所有数据都要求实时采集、传输、计算,传统 TCP 和 RDMA 网络都无法完美适配云时代的存储需求。 ESSD是业内首个百万级 IOPS 、百微秒延时云存储产品,相当于一个千万平米的巨型数据仓库,自带时速超过120公里的超级高速,仅需1秒就可以完成1部高清电影的传输和存储。 其优异的性能得益于阿里云的多项技术自研,底层架构基于自研大规模分布式存储系统盘古 2.0,存储芯片采用自研Aliflash SSD,并且依托自研网络协议 Luna 和增强型RDMA 数据传输协议,结合自研HPCC流控算法,深度优化TCP,大幅降低计算资源消耗及响应延时,使ESSD的数据传输效率可提高50%。 采用全新网络协议的ESSD已正式商用,目前服务数万企业,涵盖自动驾驶、工业物联网、AR/VR、证券交易、电商搜索等数据高并发领域。 “ESSD为企业数据存储和业务敏捷创新提供了新的可能,成为AIoT海量数据存储场景的标配。”阿里云智能存储产品资深总监Alex Chen表示。 阿里云拥有全球最丰富的云存储产品家族,总数据存储量达数十EB,凭借多层次防护、跨区域容灾等能力连续三年入选Gartner全球云存储魔力象限,并且被列为全球领导者地位。 本文作者:阿里云头条阅读原文 本文为云栖社区原创内容,未经允许不得转载。

August 27, 2019 · 1 min · jiezi

图数据库-Nebula-Graph-v100beta-已上线

Nebula Graph:一个开源的分布式图数据库。作为唯一能够存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不仅能够在高并发场景下满足毫秒级的低时延查询要求,还能够实现服务高可用且保障数据安全性。Nebula Graph v1.0.0-beta 版本已发布,更新内容如下: Storage Engine支持集群部署引入 Raft 一致性协议,支持 Leader 切换存储引擎支持 HBase新增从 HDFS 导入数据功能查询语言 nGQL新增注释功能创建 Space 支持默认属性,新增 SHOW SPACE 和 DROP SPACE 功能新增获取某 Tag 或 EdgeType 属性功能新增获取某 Tag 或 EdgeType 列表功能新增 DISTINCT 过滤重复数据新增 UNION , INTERSECT 和 MINUS 集合运算新增 FETCH 获取指定 Vertex 相应 Tag 的属性值WHERE 和 YIELD 支持用户定义变量和管道操作WHERE 和 YIELD 支持算术和逻辑运算新增 ORDER BY 对结果集排序支持插入多条点或边支持 HOSTS 的 CRUD 操作Tools新增 Java importer - 从 CSV 导入数据package_build -  支持 Linux 发行指定版本的软件包perf tool - Storage Service 压测工具Console 支持关键字自动补全功能ChangeLog$$[tag].prop` 变更为 `$$.tag.prop , $^[tag].prop 变更为 $^.tag.prop 重构运维脚本 nebula.service附录最后是 Nebula 的 GitHub 地址,欢迎大家试用,有什么问题可以向我们提 issue。GitHub 地址:github.com/vesoft-inc/nebula  ;加入 Nebula Graph 交流群,请联系 Nebula Graph 官方小助手微信号:NebulaGraphbot ...

August 20, 2019 · 1 min · jiezi

SOFAStack-活动回顾整理集合含视频回顾

SOFAStack 是蚂蚁金服完全自主研发的金融级分布式架构,包含了构建金融级云原生架构所需的各个组件,如微服务研发框架、RPC 框架、服务注册中心、分布式定时任务、限流/熔断框架、动态配置推送、分布式链路追踪、Metrics 监控度量、分布式高可用消息队列、分布式事务框架和分布式数据库代理层等。 SOFAStack:https://github.com/sofastack 本文为 SOFAStack 相关线上线下活动的回顾集合,并且会不定时更新。 / SOFAChannel 线上直播系列 /SOFAChannel#7扩展 Kubernetes 实现金融级云原生发布部署 - 自定义资源 CAFEDeployment 的背景、实现和演进视频回顾资料:https://tech.antfin.com/community/live/737SOFAChannel#6蚂蚁金服轻量级监控分析系统解析 | SOFAChannel#6 直播整理视频回顾资料:https://tech.antfin.com/community/live/687SOFAChannel#5给研发工程师的代码质量利器 | SOFAChannel#5 直播整理视频回顾资料:https://tech.antfin.com/community/live/552SOFAChannel#4分布式事务 Seata TCC 模式深度解析 | SOFAChannel#4 直播整理视频回顾资料:https://tech.antfin.com/community/live/462SOFAChannel#3SOFARPC 性能优化实践(下)| SOFAChannel#3 直播整理视频回顾资料:https://tech.antfin.com/community/live/245SOFAChannel#2SOFARPC 性能优化实践(上)| SOFAChannel#2 直播整理视频回顾资料:https://tech.antfin.com/community/live/244SOFAChannel#1从蚂蚁金服微服务实践谈起 | SOFAChannel#1 直播整理视频回顾资料:https://tech.antfin.com/community/live/148/ SOFAMeetup 系列 /SOFAMeetup#3<广州站>分布式事务 Seata Saga 模式首秀以及三种模式详解 | Meetup#3 回顾视频回顾资料:https://tech.antfin.com/community/activities/779/review/901 SOFAMeetup#2<上海站>当 Spring Cloud 遇上 SOFAStack | Meetup#2 回顾视频回顾资料:https://tech.antfin.com/community/activities/576/review/817 基于 SOFAArk 和 SOFADashboard 实现动态模块管控 | Meetup#2 回顾视频回顾资料:https://tech.antfin.com/community/activities/576/review/819 SOFAMeetup#1<北京站>蚂蚁金服开源服务注册中心 SOFARegistry | SOFA 开源一周年献礼视频回顾资料:https://tech.antfin.com/community/activities/382/review/710 ...

August 20, 2019 · 1 min · jiezi

Kafka-原理和实战

本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/bV8AhqAjQp4a_iXRfobkCQ 作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双语班)。先后从事过电子商务、开放平台、移动浏览器、推荐广告和大数据、人工智能等相关开发和架构。目前在vivo智能平台中心从事 AI中台建设以及广告推荐业务。擅长各种业务形态的业务架构、平台化以及各种业务解决方案。博客地址:http://arganzheng.life。背景最近要把原来做的那套集中式日志监控系统进行迁移,原来的实现方案是: Log Agent => Log Server => ElasticSearch => Kibana,其中Log Agent和Log Server之间走的是Thrift RPC,自己实现了一个简单的负载均衡(WRB)。 原来的方案其实运行的挺好的,异步化Agent对应用性能基本没有影响。支持我们这个每天几千万PV的应用一点压力都没有。不过有个缺点就是如果错误日志暴增,Log Server这块处理不过来,会导致消息丢失。当然我们量级没有达到这个程度,而且也是可以通过引入队列缓冲一下处理。不过现在综合考虑,其实直接使用消息队列会更简单。PRC,负载均衡,负载缓冲都内建实现了。另一种方式是直接读取日志,类似于logstash或者flume的方式。不过考虑到灵活性还是决定使用消息队列的方式,反正我们已经部署了Zookeeper。调研了一下,Kafka是最适合做这个数据中转和缓冲的。于是,打算把方案改成: Log Agent => Kafka => ElasticSearch => Kibana。 Kafka介绍一、Kafka基本概念Broker:Kafka集群包含一个或多个服务器,这种服务器被称为broker。Topic:每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。Message 消息是Kafka通讯的基本单位,有一个固定长度的消息头和一个可变长度的消息体(payload)构成。在Java客户端中又称之为记录(Record)。消息结构各部分说明如下: CRC32: CRC32校验和,4个字节。magic: Kafka服务程序协议版本号,用于做兼容。1个字节。attributes: 该字段占1字节,其中低两位用来表示压缩方式,第三位表示时间戳类型(0表示LogCreateTime,1表示LogAppendTime),高四位为预留位置,暂无实际意义。timestamp: 消息时间戳,当 magic > 0 时消息头必须包含该字段。8个字节。key-length: 消息key长度,4个字节。key: 消息key实际数据。payload-length: 消息实际数据长度,4个字节。payload: 消息实际数据在实际存储一条消息还包括12字节的额外开销(LogOverhead): 消息的偏移量: 8字节,类似于消息的Id。消息的总长度: 4字节Partition: Partition(分区)是物理上的概念,每个Topic包含一个或多个Partition。每个分区由一系列有序的不可变的消息组成,是一个有序队列。每个分区在物理上对应为一个文件夹,分区的命名规则为${topicName}-{partitionId},如__consumer_offsets-0。分区目录下存储的是该分区的日志段,包括日志数据文件和两个索引文件。每条消息被追加到相应的分区中,是顺序写磁盘,因此效率非常高,这也是Kafka高吞吐率的一个重要保证。kafka只能保证一个分区内的消息的有序性,并不能保证跨分区消息的有序性。LogSegment: 日志文件按照大小或者时间滚动切分成一个或者多个日志段(LogSegment),其中日志段大小由配置项log.segment.bytes指定,默认是1GB。时间长度则是根据log.roll.ms或者log.roll.hours配置项设置;当前活跃的日志段称之为活跃段(activeSegment)。不同于普通的日志文件,Kafka的日志段除了有一个具体的日志文件之外,还有两个辅助的索引文件: 数据文件 数据文件是以 .log 为文件后缀名的消息集文件(FileMessageSet),用于保存消息实际数据命名规则为:由数据文件的第一条消息偏移量,也称之为基准偏移量(BaseOffset),左补0构成20位数字字符组成每个数据文件的基准偏移量就是上一个数据文件的LEO+1(第一个数据文件为0)偏移量索引文件 文件名与数据文件相同,但是以.index为后缀名。它的目的是为了快速根据偏移量定位到消息所在的位置。首先Kafka将每个日志段以BaseOffset为key保存到一个ConcurrentSkipListMap跳跃表中,这样在查找指定偏移量的消息时,用二分查找法就能快速定位到消息所在的数据文件和索引文件然后在索引文件中通过二分查找,查找值小于等于指定偏移量的最大偏移量,最后从查找出的最大偏移量处开始顺序扫描数据文件,直到在数据文件中查询到偏移量与指定偏移量相等的消息需要注意的是并不是每条消息都对应有索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引,我们可以通过index.interval.bytes设置索引跨度。时间戳索引文件 Kafka从0.10.1.1版本开始引入了一个基于时间戳的索引文件,文件名与数据文件相同,但是以.timeindex作为后缀。它的作用则是为了解决根据时间戳快速定位消息所在位置。Kafka API提供了一个 offsetsForTimes(Map<TopicPartition, Long> timestampsToSearch)方法,该方法会返回时间戳大于等于待查询时间的第一条消息对应的偏移量和时间戳。这个功能其实挺好用的,假设我们希望从某个时间段开始消费,就可以用offsetsForTimes()方法定位到离这个时间最近的第一条消息的偏移量,然后调用seek(TopicPartition, long offset)方法将消费者偏移量移动过去,然后调用poll()方法长轮询拉取消息。Producer: 负责发布消息到Kafka broker。生产者的一些重要的配置项: request.required.acks: Kafka为生产者提供了三种消息确认机制(ACK),用于配置broker接到消息后向生产者发送确认信息,以便生产者根据ACK进行相应的处理,该机制通过属性request.required.acks设置,取值可以为0, -1, 1,默认是1。 acks=0: 生产者不需要等待broker返回确认消息,而连续发送消息。acks=1: 生产者需要等待Leader副本已经成功将消息写入日志文件中。这种方式在一定程度上降低了数据丢失的可能性,但仍无法保证数据一定不会丢失。因为没有等待follower副本同步完成。acks=-1: Leader副本和所有的ISR列表中的副本都完成数据存储时才会向生产者发送确认消息。为了保证数据不丢失,需要保证同步的副本至少大于1,通过参数min.insync.replicas设置,当同步副本数不足次配置项时,生产者会抛出异常。但是这种方式同时也影响了生产者发送消息的速度以及吞吐率。message.send.max.retries: 生产者在放弃该消息前进行重试的次数,默认是3次。retry.backoff.ms: 每次重试之前等待的时间,单位是ms,默认是100。queue.buffering.max.ms: 在异步模式下,消息被缓存的最长时间,当到达该时间后消息被开始批量发送;若在异步模式下同时配置了缓存数据的最大值batch.num.messages,则达到这两个阈值的任何一个就会触发消息批量发送。默认是1000ms。queue.buffering.max.messages: 在异步模式下,可以被缓存到队列中的未发送的最大消息条数。默认是10000。queue.enqueue.timeout.ms: ...

August 19, 2019 · 6 min · jiezi

OceanBase高可用实践

背景高可用是构建分布式系统的基石。一方面,出于成本考虑, 分布式系统往往采取比较廉价的硬件,其可靠性相对于小型机、专有硬件有很大的不足, 而分布式系统的规模一般比较大,假如硬件的可靠性只有三个9(99.9%), 一个1000台机器规模的集群每天将面临1台机器宕机的风险,在如此大规模的情况下,存储介质,比如硬盘可能会随时都有损坏,结点之间的网络可能随时都会有抖动,机房可能局部或整体断电,地区或数据中心可能会出现不可用,如果不在设计时考虑这些问题,当这些情况出现的时候,系统将很快处于不可用的状态;另一方面,分布式系统的程序在设计与实现上也更为复杂,软件上既要容错硬件的不可靠,同时软件自身也有可能有问题, 在对外部环境容错的同时需要考虑对软件BUG的容错。 OceanBase在设计之初就充分考虑了高可用问题,确保OceanBase有能力在这些异常出现后,仍然能最大可能的提供服务。 高可用的基本策略冗余是实现高可用的通用方法,为防止数据丢失,将数据冗余多份;为防止系统中某些节点故障,对某些功能节点进行冗余。 冗余带来的好处是可以抵御某些节点的损失,而带来的坏处则主要是成本、性能和一致性问题。 成本主要包括额外的存储、网络、机柜等硬件成本,这是构建高可用分布式系统的必不可少的开销,其总体成本较专有硬件仍然要低,因为专有硬件实际上也需要在内部对某些模块进行冗余以获取高可用性。 性能和一致性问题则是高可用分布式系统必须要处理问题,这两个问题直接影响整个系统正确性、延时与吞吐量。 在传统myql或oracle中,我们往往通过添加备机来实现高可用,且为了实现高性能和高可用,一般会使用“最大可用”模式: 主机尽力将数据同步到备机,而不管是否同步成功,当主机挂掉以后,将备机升级成主机以继续提供服务,这就意味着如果主机在宕机前有数据没有同步到备机,要么通过某种特殊的手段将数据从宕掉的主机同步到备机,要么就接受暂时的数据不一致而继续提供服务,在这种情况下,如果出现主机永久损坏,则会造成数据丢失: 为了解决这个问题,可以使用最大保护模式(早期的MySQL版本不支持),即主机将日志同步到备机成功后再应答客户,这样会引入另外一个问题,即备机故障或网络抖动会导致失败,影响可用性; 小微引入了共享存储,将数据库redo log放在共享存储上,主机宕机以后,备机需要确保主机所有的数据都已经同步才能对外提供服务: 这样在主机宕机时,备机作一些额外的检查后升级为主机继续提供服务,这样可以确保数据一致性,但引入了共享存储。传统的主备模式还有另外一个问题是主备之间无法通过自身决出主备,需要人工切换或者使用一个第三方组件: 但是又引入了HA模块的稳定性问题,如果HA模块和主机的网络不通, HA将不能识别主机是活着还是网络有问题,此时HA如果进行切换而主机还活着则会造成后果很严重的双主问题。 OceanBase高可用策略故障可以分为单机故障(磁盘、内存等硬件介质损坏或单台软件Crash都属于单机故障),机架/机房故障(比如整个机架或机房的电源断电)以及地区/数据中心(比如地区地震造成该区网络隔离)故障,一般来说,故障单位越小,出现频率越高,而除非自然灾害,一个地区出现故障的概率极小,故障单位越小,实现高可用的难度和成本越低,故障单位越大,由于引入环境、距离等因素,实现高可用的难度和成本会呈指数倍增长。比如为了预防单机故障,只需要在本机房预备冗余节点,故障时通过某些技术方案,可以做到实时切换;而为了预防数据中心故障,则需要在另外一个地区预备冗余的数据中心,在故障时由于通信距离等原因,基本上无法做到无损切换。 OceanBase虽然在设计之初就考虑到了硬件和软件的不可靠,但OceanBase的高可用并非一蹴而就,在实现过程中,为了快速实现或者绕过某个暂时无法攻克的技术难点,会进行综合权衡,只实现一些出现概率较高的基本高可用策略,而通过人肉或其它手段来保证在某些很难出现的灾难出现后可以尽快恢复。然后通过逐步迭代,逐渐完善,将高可用的范围提高,比如OceanBase最初的时候只考虑单机故障的高可用,到目前为止已经可以实现同城IDC之间的容灾。 分布式系统为了设计与实现的简单,往往会在系统中设置一个全局单点,来负责相对比较轻量的管理任务, OceanBase中的rootserver就是这样一个角色;它主要负责集群中其它角色的管理并作为用户的入口,通常其压力不高且无本地数据需要存储,所需信息都可以通过其它角色的汇报来重建。 而作为一个分布式数据库,OceanBase面临着两个很难解决的问题:数据一致性与分布式事务,在早期的OceanBase版本中,采取的策略是暂时绕过这两个问题,等技术积累到一定程度后再回过头来解决,所以在OceanBase中另外增加了一个单写入节点,这个节点的压力很高,数据无法通过其它节点来恢复,我们需要保证这些单节点的高可用。另外一个是保存基线数据结点的高可用,这些结点被设计成可以弹性伸缩,本身具备高可用属性,但仍然需要考虑磁盘故障以及数据副本之间的一致性。 我们会在下面的章节分别描述对这两类节点的高可用策略。 系统单点在早期OceanBase的版本中,主要依靠主备来为单点提供高可用, 使用两台机器,其中的一台角色为主的机器对外提供服务,另外一台机器做为热备, 当主机挂掉后,备机切换为主,继续提供服务。 如前所述,这种“最大可用”模式的主备机制主要有两个问题:第一个问题在于这两台机器无法通过自身来决出主备,必须要依赖于一个第三方组件,早期我们使用了HA(linux-ha.org) 来做为仲裁组件,HA使用VIP机制,两台机器共享VIP, 同一时刻VIP只会加载在其中的一台机器, VIP会提供给外部应用程序作为OceanBase集群的入口地址,即VIP加载在哪一台机器上,该机就会作为主对外提供服务,程序可以通过不断检测VIP是否存在来判断本机是否为主机,当HA通过我们提供的检测程序检测到主机故障后,就会将VIP切换到备机, 此时外部请求就会路由到原来的备机,原来的备机检测到VIP“飘”到本机后,会将自己的角色置为主: 使用HA主要有几个问题: HA为了防止网络抖动带来的误判,要求将两台机器使用网线直连, 这就限制了两台机器只能放在一个机柜,如果整个机柜断电,则服务不可用,这样就不能抵御机柜以及机房的容灾。数据一致性不能保证,一般不要求使用HA的角色持久化特别重要的数据。 其数据应该能通过其他角色的汇报而重建。另外一个问题在于这种机制无法保证数据不丢失, 某些极端情况下需要停机恢复,如果有机器永久损失,则可能会造成数据的丢失,在某些业务上可能无法接受。 而Updateserver是OceanBase中至关重要的节点,其数据丢失直接影响用户,也不能通过其它类型节点来重建,所以Updateserver最早抛弃HA模式,而改为通过Rootserver来选主: Updateserver每次写入都会生成一条日志,每条日志有一个惟一且单调递增的日志号, 各Updateserver向Rootserver汇报自己的日志号, Rootserver选取日志号最大的Updateserver为主并发放租约,备Updateserver同时需要向主Updateserver注册,由主Updateserver发放租约。Updateserver使用一主多备的形式, 每次写入必须要写入多数派个节点成功才能应答客户,写入请求首先发送到主Updateserver,主Updateserver生成日志并同步到备机,收到多数派个成功回应以后应答客户。如果收不到足够多的回应,则不会应答客户端,该条写入可能生效,也可能不生效。 由于要求写入多数派个节点才算成功,所以主备间的网络延迟不能太高,目前OceanBase要求updateserver主备分布在同城的不同IDC, 如果采取一主两备的模式, 最大可以容忍一个同城IDC故障。 当某一台机器同步日志失败时,主机会将其剔除在恢复之前不再向其同步日志, 这对网络要求很高,如果网络连续出现抖动,则会造成可用性问题。在最新版本OceanBase, 将同步日志的方式也改为Paxos方式,一条日志只需要写到多数派个结点上成功便为成功,不需要各台备机顺序回应,进一步容忍短暂的网络问题。 虽然Updateserver去掉了对HA的依赖,但Rootserver仍然需要HA来选主,由于HA无法部署在两个IDC,所以我们对IDC之间的容灾使用的策略是在另外一个IDC部署一个备集群,在主集群出现故障时,通过人肉的方式将备集群切换为主来提供服务。 基于这个原因,OceanBase 在0.5里彻底取消了基于HA的主备机制,而是通过使用类似paxos的算法来进行选举: 让程序自身投票来决出主备, 当一台机器得到多数派的认可,它即可以成为主,这样系统能容忍一定数量节点的不可用,比如,如果是2台,则不能容忍有机器宕机,3台则可以容忍一台机器宕机, 3台机器可以部署在不同的机房以容忍机房故障。 Updateserver仍然通过Rootserver来选主,但这样也存在一个问题,当Updateserver和Rootserver同时故障的时候,Updateserver必须要等Rootserver恢复完成后才能恢复,增加了故障恢复的时间 。在后续的OceanBase版本中,将去除Updateserver这个单写入节点,并将其选主的权力下放到自身,摆脱由Rootserver选主的局面。届时Rootserver的工作会更为简单,单点不会成为OceanBase的瓶颈。 基线数据Rootserver/Updateserver是通过冗余节点来进行容灾,备节点一般不提供服务或只提供有限的服务,基线数据则是通过冗余数据来实现高可用与扩展服务能力。通过冗余3~6份数据来提供更多的服务能力。冗余的数据不能存储在相同的机器上,以避免机器宕机后损失可用性。同时在可能的情况下,数据需要分布在不同的机架上,以抵御整机架断电或断网,OceanBase在早期的实现中,为了简化实现与对机器分布的要求,未考虑数据分布在不同的机柜,曾出现过整机架断网而造成服务不可用。 基线数据的副本数决定了一个集群同时有多少台机器可以宕机,如果使用三副本,则同时可以有两台机器宕机,每个基线数据结点都和Rootserver保持心跳,当该结点宕机以后,rootserver会检测到并根据目前系统中所拥有的副本数量启动复制,为了避免因网络抖动所带来的不必要的副本复制,我们设定在安全的情况下(比如剩余副本数大于1) 可以容忍副本丢失一段时间(比如8小时),当副本丢失超出该时长后才启动复制。 ...

August 19, 2019 · 1 min · jiezi

分布式ID系列5Twitter的雪法算法Snowflake适合做分布式ID吗

写到这里,分布式Id算是写到最后一篇了,在这一篇里,我会讲到目前网上最适合分布式Id的方法,什么方法呢,请您往下看: 介绍Snowflake算法SnowFlake算法是国际大公司Twitter的采用的一种生成分布式自增id的策略,这个算法产生的分布式id是足够我们我们中小公司在日常里面的使用了。我也是比较推荐这一种算法产生的分布式id的。 算法snowflake的生成的分布式id结构组成部分算法snowflake生成id的结果是一个64bit大小的整数,它的结构如下图, 这里我么来讲一下这个结构:首先因为window是64位的,然后整数的时候第一位必须是0,所以最大的数值就是63位的111111111111111111111111111111111111111111111111111111111111111,然后呢Snowflake算法分出来41位作为毫秒值,然后10位作为redis节点的数量,然后12位做成redis节点在每一毫秒的自增序列值 41位的二进制11111111111111111111111111111111111111111转换成10进制的毫秒就是2199023255551,然后我们把 2199023255551转换成时间就是2039-09-07,也就是说可以用20年的(这里在网上会有很多说是可以使用69年的,他们说69年的也对,因为1970年+69年的结果就是2039年,但是如果从今年2019年来说,也就只能用20年了) 然后10位作为节点,所以最多就是12位的1111111111,也就是最多可以支持1023个节点, 然后10位表示每一个节点自增序列值,这里最多就是10位的111111111111,也就是说每一个节点可以每一毫秒可以最多生成4059个不重复id值 由于在Java中64bit的整数是long类型,所以在Java中SnowFlake算法生成的id就是long来存储的。 Java实现Snowflake算法的源码Snowflake算法的源码如下所示(这个是我从网上找到的),这里我进行了测试了一波,结果如下所示 package com.hello;import java.text.SimpleDateFormat;import java.util.Date;public class Test { /** * 开始时间截 (1970-01-01) */ private final long twepoch = 0L; /** * 机器id所占的位数 */ private final long workerIdBits = 5L; /** * 数据标识id所占的位数 */ private final long datacenterIdBits = 5L; /** * 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ private final long maxWorkerId = -1L ^ (-1L << workerIdBits); /** * 支持的最大数据标识id,结果是31 */ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); /** * 序列在id中占的位数 */ private final long sequenceBits = 12L; /** * 机器ID向左移12位 */ private final long workerIdShift = sequenceBits; /** * 数据标识id向左移17位(12+5) */ private final long datacenterIdShift = sequenceBits + workerIdBits; /** * 时间截向左移22位(5+5+12) */ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; /** * 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */ private final long sequenceMask = -1L ^ (-1L << sequenceBits); /** * 工作机器ID(0~31) */ private long workerId; /** * 数据中心ID(0~31) */ private long datacenterId; /** * 毫秒内序列(0~4095) */ private long sequence = 0L; /** * 上次生成ID的时间截 */private long lastTimestamp = -1L; public Test(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; } /** * 获得下一个ID (该方法是线程安全的) * * @return SnowflakeId */ public synchronized long nextId() { long timestamp = timeGen(); //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 if (timestamp < lastTimestamp) { throw new RuntimeException( String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } //如果是同一时间生成的,则进行毫秒内序列 if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; //毫秒内序列溢出 if (sequence == 0) { //阻塞到下一个毫秒,获得新的时间戳 timestamp = tilNextMillis(lastTimestamp); } } //时间戳改变,毫秒内序列重置 else { sequence = 0L; } //上次生成ID的时间截 lastTimestamp = timestamp; //移位并通过或运算拼到一起组成64位的ID return ((timestamp - twepoch) << timestampLeftShift) // | (datacenterId << datacenterIdShift) // | (workerId << workerIdShift) // | sequence; } /** * 阻塞到下一个毫秒,直到获得新的时间戳 * * @param lastTimestamp 上次生成ID的时间截 * @return 当前时间戳 */ protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } /** * 返回以毫秒为单位的当前时间 * * @return 当前时间(毫秒) */ protected long timeGen() { return System.currentTimeMillis(); } public static void parseId(long id) { long miliSecond = id >>> 22; long shardId = (id & (0xFFF << 10)) >> 10; System.err.println("分布式id-"+id+"生成的时间是:"+new SimpleDateFormat("yyyy-MM-dd").format(new Date(miliSecond))); } public static void main(String[] args) { Test idWorker = new Test(0, 0); for (int i = 0; i < 10; i++) { long id = idWorker.nextId(); System.out.println(id); parseId(id); } }}执行结果如下所示,此时我们可以看到,不仅可以可以把分布式id给创建处理,而且可以把这个创建的时间也打印出来,此时就可以满足我们的分布式id的创建了 ...

August 19, 2019 · 4 min · jiezi

DLedger-基于-raft-协议的-commitlog-存储库

“点击获取上云帮助文档” 尊敬的阿里云用户: 您好!为方便您试用开源 RocketMQ 客户端访问阿里云MQ,我们申请了专门的优惠券,优惠券可以直接抵扣金额。请填写下您公司账号信息,点击上图,了解更多哦。 一、DLedger引入目的 在 RocketMQ 4.5 版本之前,RocketMQ 只有 Master/Slave 一种部署方式,一组 broker 中有一个 Master ,有零到多个 Slave,Slave 通过同步复制或异步复制的方式去同步 Master 数据。Master/Slave 部署模式,提供了一定的高可用性。 但这样的部署模式,有一定缺陷。比如故障转移方面,如果主节点挂了,还需要人为手动进行重启或者切换,无法自动将一个从节点转换为主节点。因此,我们希望能有一个新的多副本架构,去解决这个问题。 新的多副本架构首先需要解决自动故障转移的问题,本质上来说是自动选主的问题。这个问题的解决方案基本可以分为两种: 利用第三方协调服务集群完成选主,比如 zookeeper 或者 etcd。这种方案会引入了重量级外部组件,加重部署,运维和故障诊断成本,比如在维护 RocketMQ 集群还需要维护 zookeeper 集群,并且 zookeeper 集群故障会影响到 RocketMQ 集群。利用 raft 协议来完成一个自动选主,raft 协议相比前者的优点是不需要引入外部组件,自动选主逻辑集成到各个节点的进程中,节点之间通过通信就可以完成选主。因此最后选择用 raft 协议来解决这个问题,而 DLedger 就是一个基于 raft 协议的 commitlog 存储库,也是 RocketMQ 实现新的高可用多副本架构的关键。 二、DLedger 设计理念1. DLedger 定位 Raft 协议是复制状态机的实现,这种模型应用到消息系统中就会存在问题。对于消息系统来说,它本身是一个中间代理,commitlog 状态是系统最终状态,并不需要状态机再去完成一次状态构建。因此 DLedger 去掉了 raft 协议中状态机的部分,但基于raft协议保证commitlog 是一致的,并且是高可用的。 另一方面 DLedger 又是一个轻量级的 java library。它对外提供的 API 非常简单,append 和 get。Append 向 DLedger 添加数据,并且添加的数据会对应一个递增的索引,而 get 可以根据索引去获得相应的数据。因此 DLedger 是一个 append only 的日志系统。 ...

August 8, 2019 · 2 min · jiezi

蚂蚁金服-3-个项目进入-CNCF-云原生全景图-开源

2019 年 6 月 25 日,全球知名开源组织云原生计算基金会 CNCF 宣布,蚂蚁金服正式成为 CNCF 黄金会员,蚂蚁金服表示将持续加大对开源项目的支持,包括 Kubernetes,ServiceMesh,Serverless,安全容器等方向,并发挥自己的力量。SOFAStack 作为蚂蚁金服重要的开源项目,最近也与 CNCF 有故事发生。近期,CNCF 发布了最新版本的 Cloud Native Landscape,蚂蚁金服金融级分布式架构 SOFAStack 中有 3 个项目被纳入,分别是 Service Mesh 数据平面代理 SOFAMosn、分布式链路跟踪系统 SOFATracer 和 RPC 服务框架 SOFARPC。 CNCF & CNCF Cloud Native LandscapeCNCF(Cloud Native Computing Foundation),是由 Google 牵头创立的云原生计算开源软件基金会。它致力于云原生(Cloud Native)技术的普及和可持续发展。2016 年 11 月,CNCF 开始维护 Cloud Native Landscape,汇总流行热门的云原生技术与工具,并加以分类,为企业构建云原生体系提供参考,在云生态研发、运维领域具有广泛影响力。 SOFAStack & CNCF Cloud Native Landscape蚂蚁金服金融级分布式架构 SOFAStack 中的 3 个项目加入这次最新版本的 Cloud Native Landscape ,分别是 Service Mesh 数据平面代理 SOFAMosn、分布式链路跟踪系统 SOFATracer 和 RPC 服务框架 SOFARPC。 ...

August 7, 2019 · 1 min · jiezi

网易云音乐的消息队列改造之路

十年文案老司机,不如网易评论区。 网易云音乐自2013年上线后,业务保持了高速增长。云音乐除了提供好听的音乐外,还留下了我们在乐和人上的美好回忆。本文整理自网易云音乐消息队列负责人林德智在近期 Apache Flink&RocketMQ Meetup 上海站的分享,通过该文,您将了解到: 网易云音乐消息队列改造背景网易云音乐业务对消息队列要求网易云音乐消息队列架构设计网易云音乐消息队列部分高级特性介绍网易云音乐消息队列落地使用情况网易云音乐消息队列未公开规划背景网易云音乐从13年4月上线以来,业务和用户突飞猛进。后台技术也从传统的 Tomcat 集群到分布式微服务快速演进和迭代,在业务的不断催生下,诞生了云音乐的 RPC,API 网关和链路跟踪等多种服务,消息队列也从 RabbitMQ 集群迁移到 Kafka集群。对于消息队列,更多处于使用阶段,也在使用中出现很多问题。因此我们期望提供一种完全可控,出现问题我们自己能排查,能跟踪,可以根据业务需求做定制改造的消息队列。 调研结果 RabbitMQ 由于持久化场景下的吞吐量只有2.6万,不能满足我们业务吞吐量的需求,云音乐在 2017 年将消息队列从 RabbitMQ 迁移到 Kafka 也是这个原因,因此不再考虑范围之内。由于云音乐整体业务的 QPS 较高,因此,ActiveMQ 也不在考虑范围。 这里主要对比 RocketMQ 与 Kafka: Kafka 更偏向大数据,日志处理,缺少死信,消费失败自动重试,事物消息,定时消息,消息过滤,广播消息等特性,另外 Kafka 没有同步刷盘。云音乐的业务更偏向于多 Topic,死信可溯源,消费失败可收敛自动重试,高可用,自动 Failover 等特性。对于商城和社交业务来说,事物,顺序 Topic 使用会比较多。Kafka 和RocketMQ 对比 : http://jm.taobao.org/2016/03/24/rmq-vs-kafka 经过 RabbitMQ,Kafka 和 RocketMQ( ActiveMQ 性能较差,暂不考虑)的调研和分析后,我们发现 RocketMQ 比较适合云音乐的通用业务,但是开源 RocketMQ 也有一些缺陷,只有我们解决了这些缺陷才能在业务中大规模使用。 开源 RocketMQ 的基本架构如下:(基本介绍参考) 开源 RocketMQ 主要问题有: Broker 仅提供了 Master 到 Slave 的复制,没有 Failover 切换的能力;事物消息不开源(我们开始研发时不开源);消息发送消费无追踪(我们开始研发时不开源);告警与监控体系没有;开源控制台不完善。云音乐业务对消息队列的要求 ...

July 26, 2019 · 2 min · jiezi

程序员修神之路分布式缓存的一条明路附代码

问题分析通过以上对话,各位是否能够猜到所有缓存穿透的原因呢?回答之前我们先来看一下缓存策略的具体代码 缓存服务器IP=hash(key)%服务器数量这里还要多说一句,key的取值可以根据具体业务具体设计。比如,我想要做负载均衡,key可以为调用方的服务器IP;获取用户信息,key可以为用户ID;等等。 在服务器数量不变的情况下,以上设计没有问题。但是要知道,程序员的现实世界是悲惨的,唯一不变的就是业务一直在变。我本无奈,只能靠技术来改变这种状况。 假如我们现在服务器的数量为10,当我们请求key为6的时候,结果是4,现在我们增加一台服务器,服务器数量变为11,当再次请求key为6的服务器的时候,结果为5.不难发现,不光是key为6的请求,几乎大部分的请求结果都发生了变化,这就是我们要解决的问题, 这也是我们设计分布式缓存等类似场景时候主要需要注意的问题。 我们终极的设计目标是:在服务器数量变动的情况下 尽量提高缓存的命中率(转移的数据最少)缓存数据尽量平均分配解决方案通过以上的分析我们明白了,造成大量缓存失效的根本原因是公式分母的变化,如果我们把分母保持不变,基本上可以减少大量数据被移动 分母不变方案如果基于公式:缓存服务器IP=hash(key)%服务器数量 我们保持分母不变,基本上可以改善现有情况。我们选择缓存服务器的策略会变为: 缓存服务器IP=hash(key)%N (N为常数)N的数值选择,可以根据具体业务选择一个满足情况的值。比如:我们可以肯定将来服务器数量不会超过100台,那N完全可以设定为100。那带来的问题呢?目前的情况可以认为服务器编号是连续的,任何一个请求都会命中一个服务器,还是以上作为例子,我们服务器现在无论是10还是增加到11,key为6的请求总是能获取到一台服务器信息,但是现在我们的策略公式分母为100,如果服务器数量为11,key为20的请求结果为20,编号为20的服务器是不存在的。 以上就是简单哈希策略带来的问题(简单取余的哈希策略可以抽象为连续的数组元素,按照下标来访问的场景) 为了解决以上问题,业界早已有解决方案,那就是一致性哈希。 一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用。一致性哈希具体的特点,请各位百度,这里不在详细介绍。至于解决问题的思路这里还要强调一下: 首先求出服务器(节点)的哈希值,并将其配置到环上,此环有2^32个节点。采用同样的方法求出存储数据的键的哈希值,并映射到相同的圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2^32仍然找不到服务器,就会保存到第一台服务器上 当增加新的服务器的时候会发生什么情况呢?通过上图我们可以发现发生变化的只有如黄色部分所示。删除服务器情况类似。 通过以上介绍,一致性哈希正是解决我们目前问题的一种方案。解决方案千万种,能解决问题即为好。 优化方案到目前为止方案都看似完美,但现实是残酷的。以上方案虽好,但还存在瑕疵。假如我们有3台服务器,理想状态下服务器在哈希环上的分配如下图:但是现实往往是这样:这就是所谓的哈希环偏斜。分布不均匀在某些场景下会依次压垮服务器,实际生产环境一定要注意这个问题。为了解决这个问题,虚拟节点应运而生。如上图,哈希环上不再是实际的服务器信息,而是服务器信息的映射信息,比如:ServerA-1,ServerA-2 都映射到服务器A,在环上是服务器A的一个复制品。这种解决方法是利用数量来达到均匀分布的目的,随之需要的内存可能会稍微大一点,算是空间换取设计的一种方案。 扩展阅读既然是哈希就会有哈希冲突,那多个服务器节点的哈希值相同该怎么办呢?我们可以采用散列表寻址的方案:从当前位置顺时针开始查找空位置,直到找到一个空位置。如果未找到,菜菜认为你的哈希环是不是该扩容了,或者你的分母参数是不是太小了呢。在实际的业务中,增加服务器或者减少服务器的操作要比查找服务器少的多,所以我们存储哈希环的数据结构的查找速度一定要快,具体说来本质是:自哈希环的某个值起,能快速查找第一个不为空的元素。如果你度娘过你就会发现,网上很多介绍虚拟哈希环节点个数为2^32(2的32次方),千篇一律。难道除了这个个数就不可以吗?在菜菜看来,这个数目完全必要这么大,只要符合我们的业务需求,满足业务数据即可。一致性哈希用到的哈希函数,不止要保证比较高的性能,还要保持哈希值的尽量平均分布,这也是一个工业级哈希函数的要求,一下代码实例的哈希函数其实不是最佳的,有兴趣的同学可以优化一下。有些语言自带的GetHashCode()方法应用于一致性哈希是有问题的,例如c#。程序重启之后同一个字符串的哈希值是变动的。所有需要一个更加稳定的字符串转int的哈希算法。一致性哈希解决的本质问题是:相同的key通过相同的哈希函数,能正确路由到相同的目标。像我们平时用的数据库分表策略,分库策略,负载均衡,数据分片等都可以用一致性哈希来解决。理论结合实际才是真谛(NetCore代码)以下代码经过少许修改可直接应用于中小项目生产环境 //真实节点的信息 public abstract class NodeInfo { public abstract string NodeName { get; } }测试程序所用节点信息: class Server : NodeInfo { public string IP { get; set; } public override string NodeName { get => IP; } }以下为一致性哈希核心代码: /// <summary> /// 1.采用虚拟节点方式 2.节点总数可以自定义 3.每个物理节点的虚拟节点数可以自定义 /// </summary> public class ConsistentHash { //哈希环的虚拟节点信息 public class VirtualNode { public string VirtualNodeName { get; set; } public NodeInfo Node { get; set; } } //添加元素 删除元素时候的锁,来保证线程安全,或者采用读写锁也可以 private readonly object objLock = new object(); //虚拟环节点的总数量,默认为100 int ringNodeCount; //每个物理节点对应的虚拟节点数量 int virtualNodeNumber; //哈希环,这里用数组来存储 public VirtualNode[] nodes = null; public ConsistentHash(int _ringNodeCount = 100, int _virtualNodeNumber = 3) { if (_ringNodeCount <= 0 || _virtualNodeNumber <= 0) { throw new Exception("_ringNodeCount和_virtualNodeNumber 必须大于0"); } this.ringNodeCount = _ringNodeCount; this.virtualNodeNumber = _virtualNodeNumber; nodes = new VirtualNode[_ringNodeCount]; } //根据一致性哈希key 获取node信息,查找操作请业务方自行处理超时问题,因为多线程环境下,环的node可能全被清除 public NodeInfo GetNode(string key) { var ringStartIndex = Math.Abs(GetKeyHashCode(key) % ringNodeCount); var vNode = FindNodeFromIndex(ringStartIndex); return vNode == null ? null : vNode.Node; } //虚拟环添加一个物理节点 public void AddNode(NodeInfo newNode) { var nodeName = newNode.NodeName; int virtualNodeIndex = 0; lock (objLock) { //把物理节点转化为虚拟节点 while (virtualNodeIndex < virtualNodeNumber) { var vNodeName = $"{nodeName}#{virtualNodeIndex}"; var findStartIndex = Math.Abs(GetKeyHashCode(vNodeName) % ringNodeCount); var emptyIndex = FindEmptyNodeFromIndex(findStartIndex); if (emptyIndex < 0) { // 已经超出设置的最大节点数 break; } nodes[emptyIndex] = new VirtualNode() { VirtualNodeName = vNodeName, Node = newNode }; virtualNodeIndex++; } } } //删除一个虚拟节点 public void RemoveNode(NodeInfo node) { var nodeName = node.NodeName; int virtualNodeIndex = 0; List<string> lstRemoveNodeName = new List<string>(); while (virtualNodeIndex < virtualNodeNumber) { lstRemoveNodeName.Add($"{nodeName}#{virtualNodeIndex}"); virtualNodeIndex++; } //从索引为0的位置循环一遍,把所有的虚拟节点都删除 int startFindIndex = 0; lock (objLock) { while (startFindIndex < nodes.Length) { if (nodes[startFindIndex] != null && lstRemoveNodeName.Contains(nodes[startFindIndex].VirtualNodeName)) { nodes[startFindIndex] = null; } startFindIndex++; } } } //哈希环获取哈希值的方法,因为系统自带的gethashcode,重启服务就变了 protected virtual int GetKeyHashCode(string key) { var sh = new SHA1Managed(); byte[] data = sh.ComputeHash(Encoding.Unicode.GetBytes(key)); return BitConverter.ToInt32(data, 0); } #region 私有方法 //从虚拟环的某个位置查找第一个node private VirtualNode FindNodeFromIndex(int startIndex) { if (nodes == null || nodes.Length <= 0) { return null; } VirtualNode node = null; while (node == null) { startIndex = GetNextIndex(startIndex); node = nodes[startIndex]; } return node; } //从虚拟环的某个位置开始查找空位置 private int FindEmptyNodeFromIndex(int startIndex) { while (true) { if (nodes[startIndex] == null) { return startIndex; } var nextIndex = GetNextIndex(startIndex); //如果索引回到原地,说明找了一圈,虚拟环节点已经满了,不会添加 if (nextIndex == startIndex) { return -1; } startIndex = nextIndex; } } //获取一个位置的下一个位置索引 private int GetNextIndex(int preIndex) { int nextIndex = 0; //如果查找的位置到了环的末尾,则从0位置开始查找 if (preIndex != nodes.Length - 1) { nextIndex = preIndex + 1; } return nextIndex; } #endregion }测试生成的节点 ConsistentHash h = new ConsistentHash(200, 5); h.AddNode(new Server() { IP = "192.168.1.1" }); h.AddNode(new Server() { IP = "192.168.1.2" }); h.AddNode(new Server() { IP = "192.168.1.3" }); h.AddNode(new Server() { IP = "192.168.1.4" }); h.AddNode(new Server() { IP = "192.168.1.5" }); for (int i = 0; i < h.nodes.Length; i++) { if (h.nodes[i] != null) { Console.WriteLine($"{i}===={h.nodes[i].VirtualNodeName}"); } }输出结果(还算比较均匀): ...

July 16, 2019 · 3 min · jiezi

译用SQL统一所有一种有效的语法惯用的流和表管理方法

现在还没有一个统一的流式SQL语法标准,各家都在做自己的。本文在一些业界应用的基础上提出了一个统一SQL语法的建议。Spark同样存在这个问题,社区版本在流式SQL上迟迟没有动作。EMR Spark在今年上半年提供了自己设计版本的流式SQL支持,也会在后续的更新中吸收和支持这些优秀的设计建议。 原文:https://blog.acolyer.org/2019/07/03/one-sql-to-rule-them-all/ 资料:One SQL to rule them all: an efficient and syntactically idiomatic approach to management of streams and tables Begoli et al., SIGMOD’19 在数据处理方面,似乎最终都会回归到SQL上!今天选择的这篇文章作者来自于Apache Beam,Apache Calcite以及Apache Flink的专家们,阐述了他们在构建流式处理SQL接口的经验。最终整理了一些SQL标准的扩展建议。 The thesis of this paper, supported by experience developing large open-source frameworks supporting real-world streaming use cases, is that the SQL language and relational model as-is and with minor non-intrusive extensions, can be very effective for manipulation of streaming data.这篇文章的论点是,在开发使用大规模开源框架解决现实世界的实际流式场景经验下,SQL语言及关系性模型在当前及非侵入式扩展后,对于流数据的操作非常有效。 ...

July 16, 2019 · 2 min · jiezi

长脸了阿里云这位英雄拿下了世界第一

阿里云数据库又被顶级机构点名了! 近日,全球最知名的数据管理系统评测标准化TPC组织公布了数据库领域分析性能基准测试最新排名,阿里云超大规模分析型数据库AnalyticDB登上榜首,是全球首个通过TPC严格审计认证的云数据库产品。 简单来说,AnalyticDB是一款可以对数据进行在线统计和分析的数据库,帮助企业简单快速实时挖掘数据价值。登上TPC榜首,意味着其已经成为全球最快的实时数据仓库! 目前,阿里云已经拥有国内最丰富的云数据库产品,AnalyticDB只是其中之一。 在多个数据库细分领域,阿里云已经实现了业界领先,并且已经集齐了一套最强阵容: 01在新零售场景中,数据分析师做市场趋势分析、业务在做广告投放时,都需要在PB级数据上依据不断变化的业务模型做分析探索,对业务发展方向进行决策。 而这就需要分析型数据库AnalyticDB的能力了,目前这款产品已经成为全球最快的实时数据仓库,在复杂分析场景中性能提升10倍,万亿数据多维分析仅需毫秒级。 02例如面对互联网大规模流量场景,阿里云拥有国内首款云原生数据库POLARDB,它最大的特点就是拥有极强的弹性能力,能大能小,解决了传统数据库昂贵、扩展性差、技术复杂、迭代慢的瓶颈。 技术方面,也采用了多个领先技术:容器虚拟化技术、存储与计算分离、共享分布式块存储技术,企业只需5分钟即可实现缩扩容,计算能力最高可扩展至1000核,存储容量最高可达100TB。被认为是云时代企业数据库的最佳选择。 03还有一类是擅长多度关系数据查询的。在金融欺诈检测场景中,图数据库可快速通过贷款联系人(或者联系人的联系人)信用信息,对用户进行信用评分,如果评分较低,则拒绝贷款或者提升利率。 阿里云GDB就具备这样的能力,GDB是国内首个云原生图数据库,可以对高度互连的数据集进行深度优化,用最短代码实现多度关系数据的查询与存储,提升查询效率10倍以上,查询时间降低至毫秒级。 04作为阿里云最早的云数据库产品,RDS已经成长为业界功能最丰富的数据库,支持MySQL、SQL Server、PostgreSQL 、MariaDB等主流数据库,可以满足不同场景的需求。 05传统数据库要上云,最关键的一步是保障数据库高效可靠地迁移。因为数据库承载着企业核心业务,但传统的数据库迁移工具要求数据库在迁移中必须停服,极大影响业务。 阿里云数据传输服务DTS大幅提升了数据库上云的速度,其最大的特点是采用分布式并发架构、智能分片、并行抓取技术,数据迁移最快可达100Mb/S,支持18种数据源,百PB级数据迁移业界最快。 大家不妨脑洞一下,看完这五款数据库产品,你想到了什么超级英雄? 本文作者:阿里云头条阅读原文 本文为云栖社区原创内容,未经允许不得转载。

July 16, 2019 · 1 min · jiezi

如何将Elasticsearch的快照备份至OSS

前言Elasticsearch 是一个开源的分布式 RESTful 搜索和分析引擎。它可以在近实时条件下,存储,查询和分析海量的数据。它还支持将快照备份至HDFS/S3上面,而阿里云OSS兼容S3的API,本文将介绍如何使用ES的Repository-S3插件将快照备份至OSS。 部署与配置首先,我们需要安装repository-s3,可以参考官方文档:https://www.elastic.co/guide/en/elasticsearch/plugins/7.2/repository-s3.html 启动ES,我们可以从log中看到,ES已经load了这个plugin: [2019-07-15T14:12:09,225][INFO ][o.e.p.PluginsService ] [master] loaded module [aggs-matrix-stats][2019-07-15T14:12:09,225][INFO ][o.e.p.PluginsService ] [master] loaded module [analysis-common][2019-07-15T14:12:09,225][INFO ][o.e.p.PluginsService ] [master] loaded module [ingest-common][2019-07-15T14:12:09,226][INFO ][o.e.p.PluginsService ] [master] loaded module [ingest-geoip][2019-07-15T14:12:09,226][INFO ][o.e.p.PluginsService ] [master] loaded module [ingest-user-agent][2019-07-15T14:12:09,226][INFO ][o.e.p.PluginsService ] [master] loaded module [lang-expression][2019-07-15T14:12:09,226][INFO ][o.e.p.PluginsService ] [master] loaded module [lang-mustache][2019-07-15T14:12:09,227][INFO ][o.e.p.PluginsService ] [master] loaded module [lang-painless][2019-07-15T14:12:09,227][INFO ][o.e.p.PluginsService ] [master] loaded module [mapper-extras][2019-07-15T14:12:09,227][INFO ][o.e.p.PluginsService ] [master] loaded module [parent-join][2019-07-15T14:12:09,227][INFO ][o.e.p.PluginsService ] [master] loaded module [percolator][2019-07-15T14:12:09,227][INFO ][o.e.p.PluginsService ] [master] loaded module [rank-eval][2019-07-15T14:12:09,228][INFO ][o.e.p.PluginsService ] [master] loaded module [reindex][2019-07-15T14:12:09,228][INFO ][o.e.p.PluginsService ] [master] loaded module [repository-url][2019-07-15T14:12:09,228][INFO ][o.e.p.PluginsService ] [master] loaded module [transport-netty4][2019-07-15T14:12:09,228][INFO ][o.e.p.PluginsService ] [master] loaded plugin [repository-s3][2019-07-15T14:12:12,375][INFO ][o.e.d.DiscoveryModule ] [master] using discovery type [zen] and seed hosts providers [settings][2019-07-15T14:12:12,801][INFO ][o.e.n.Node ] [master] initialized[2019-07-15T14:12:12,802][INFO ][o.e.n.Node ] [master] starting ...然后,我们需要将OSS使用的Access Key和Secret Key配置到ES去,分别执行下面的命令: ...

July 16, 2019 · 2 min · jiezi

Java秒杀系统实战系列构建SpringBoot多模块项目

摘要:本篇博文是“Java秒杀系统实战系列文章”的第二篇,主要分享介绍如何采用IDEA,基于SpringBoot+SpringMVC+Mybatis+分布式中间件构建一个多模块的项目,即“秒杀系统”!。 内容:传统的基于IDEA构建SpringBoot的项目,是直接借助Spring Initializr插件进行构建,但是这种方式在大部分情况下,只能充当“单模块”的项目,并不能很好的做到“分工明确、职责清晰”的分层原则! 故而为了能更好的管理项目代码以及尽量做到“模块如名”,快速定位给定的类文件或者其他文件的位置,下面我们将基于IDEA、借助Maven构建多模块的项目,其中,其构建的思路如下图所示: ![图片上传中...] 详细的构建过程在本文就不赘述了!文末有提供源码的地址以及构建过程的视频教程!下面重点介绍一下跟“Java秒杀系统”相关的构建步骤。 (1)如下图所示为最终构建成功的项目的整体目录结构: 从该目录结构中可以看出,该项目为一个“聚合型项目”,其中,model模块依赖api模块,server模块依赖model模块,层层依赖!最终在server模块实现“大汇总”,即server模块为整个项目的核心关键所在,像什么“配置文件”、“入口启动类”啥的都在这个模块中! 而且,各个模块的职责是不一样的,分工也很明确,就像model模块,一般人看了就知道这里放的东西应该是跟mybatis或者跟数据库mysql相关的类文件与配置文件等等。 构建好相应的模块之后,就需要往相应的模块添加依赖,即只需要在pom.xml中加入相应的依赖即可,在这里就不贴出来了!(2)在这里主要贴一下server模块入口启动类MainApplication的代码,如下所示: @SpringBootApplication@ImportResource(value = {"classpath:spring/spring-jdbc.xml"})@MapperScan(basePackages = "com.debug.kill.model.mapper")@EnableSchedulingpublic class MainApplication extends SpringBootServletInitializer{ @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(MainApplication.class); } public static void main(String[] args) { SpringApplication.run(MainApplication.class,args); }}其中,该启动类将加载配置文件spring-jdbc.xml(数据库链接信息的配置文件)! 构建完成之后,可以将整个项目采用外置的Tomcat跑起来,运行过程中,观察控制台Console的输出信息,如果没有报错信息,则代表整个项目的搭建是没有问题的!如果出现了问题,建议自己先研究一番并尝试去解决掉!如果仍旧不能解决,可以加文末提供的联系方式进行解决! (4)除此之外,为了让整个项目在前后端分离开发的情况下,前后端的接口交互更加规范(比如响应信息的规范等等),在这里我们采用了通用的一个状态码枚举类StatusCode 跟 一个通用的响应结果类BaseResponse,用于后端在返回响应信息给到前端时进行统一封装。 状态码枚举类StatusCode的源代码如下所示: public enum StatusCode { Success(0,"成功"), Fail(-1,"失败"), InvalidParams(201,"非法的参数!"), UserNotLogin(202,"用户没登录"), ; private Integer code; //状态码code private String msg; //状态码描述信息msg StatusCode(Integer code, String msg) { this.code = code; this.msg = msg; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; }}响应结果类BaseResponse的源代码如下所示: ...

July 16, 2019 · 2 min · jiezi

阿里云InfluxDB®-Raft-HybridStorage实现方案

背景阿里云InfluxDB®是阿里云基于开源版InfluxDB打造的一款时序数据库产品,提供更稳定的持续运行状态、更丰富强大的时序数据计算能力。在现有的单节点版本之外,阿里云InfluxDB®团队还将推出多节点的高可用版本。 我们知道现有的开源版InfluxDB只提供单节点的能力,早期开源的集群版本功能不完善、且社区不再提供更新与支持。经过对官网商业版InfluxDB现有文档的研究,我们猜测在商业版InfluxDB集群方案中,meta信息集群是基于一致性协议Raft做同步的,而数据是异步复制的。这种分离的方式虽然有优点,但也引起了一系列的一致性问题,在一些公开的文档中,官方也承认这种数据复制方案并不令人满意。 因此,团队在参考多项技术选型后,决定采用最为广泛使用并有较长历史积累的ETCD/Raft作为核心组件实现阿里云InfluxDB®的Raft内核,对用户所有的写入或一致性读请求直接进行Raft同步(不做meta信息同步与数据写入在一致性过程中的拆分),保证多节点高可用版本拥有满足强一致性要求的能力。 有幸笔者参与到多节点的高可用版本的开发中,期间遇到非常多的挑战与困难。其中一项挑战是ETCD的Raft框架移植过程中,在移除了ETCD自身较为复杂、对时序数据库没有太多作用的Raft日志模块后,所带来的一系列问题。本文就业界Raft日志的几种不同实现方案做讨论,并提出一种自研的Raft HybridStorage方案。 业内方案ETCD由于我们采用了ETCD/Raft的方案,绕不开讨论一下ETCD本家的Raft日志实现方式。 官网对Raft的基本处理流程总结参考下图所示,协议细节本文不做扩展: 对于ETCD的Raft日志,主要包含两个主要部分:文件部分(WAL)、内存存储部分(MemoryStorage)。 文件部分(WAL),是ETCD Raft过程所用的日志文件。Raft过程中收到的日志条目,都会记录在WAL日志文件中。该文件只会追加,不会重写和覆盖。 内存存储部分(MemoryStorage),主要用于存储Raft过程用到的日志条目一段较新的日志,可能包含一部分已共识的日志和一些尚未共识的日志条目。由于是内存维护,可以灵活的重写替换。MemoryStorage有两种方式清理释放内存:第一种是compact操作,对appliedId之前的日志进行清理,释放内存;第二种是周期snapshot操作,该操作会创建snapshot那一时刻的ETCD全局数据状态并持久化,同时清理内存中的日志。 在最新的ETCD 3.3代码仓库中,ETCD已经将Raft日志文件部分(WAL)和Raft日志内存存储部分(MemoryStorage)都抽象提升到了与Raft节点(Node)、Raft节点id以及Raft集群其他节点信息(*membership.RaftCluster)平级的Server层级,这与老版本的ETCD代码架构有较大区别,在老版本中Raft WAL与MemoryStorage都仅仅只是Raft节点(Node)的成员变量。 一般情况下,一条Raft日志的文件部分与内存存储部分配合产生作用,写入时先写进WAL,保证持久化;随之马上追加到MemoryStorage中,保证热数据的高效读取。 无论是文件部分还是内存存储部分,其存储的主要数据结构一致,都是raftpb.Entry。一条log Entry主要包含以下几个信息: 参数描述Termleader的任期号Index当前日志索引Type日志类型Data日志内容此外,ETCD Raft日志的文件部分(WAL)还会存储针对ETCD设计的一些额外信息,比如日志类型、checksum等等。 CockroachDBCockroachDB是一款开源的分布式数据库,具有NoSQL对海量数据的存储管理能力,又保持了传统数据库支持的ACID和SQL等,还支持跨地域、去中 心、高并发、多副本强一致和高可用等特性。 CockroachDB的一致性机制也是基于Raft协议:单个Range的多个副本通过Raft协议进行数据同步。Raft协议将所有的请求以Raft Log的形式串行化并由Leader同步给Follower,当绝大多数副本写Raft Log成功后,该Raft Log会标记为Committed状态,并Apply到状态机。 我们来分析一下CockroachDB Raft机制的关键代码,可以很明显的观察到也是从鼻祖ETCD的Raft框架移植而来。但是CockroachDB删除了ETCD Raft日志的文件存储部分,将Raft日志全部写入RocksDB,同时自研一套热数据缓存(raftentry.Cache),利用raftentry.Cache与RocksDB自身的读写能力(包括RocksDB的读缓存)来保证对日志的读写性能。 此外,Raft流程中的创建snapshot操作也是直接保存到RocksDB。这样实现的原因,个人推测是可能由于CockroachDB底层数据存储使用的就是RocksDB,直接使用RocksDB的能力读写WAL或者存取snapshot相对简单,不需要再额外开发适用于CockroachDB特性的Raft日志模块了。 自研HybridStorage移除snapshot在阿里云InfluxDB多节点高可用方案实现过程中,我们采用了ETCD/Raft作为核心组件,根据移植过程中的探索与InfluxDB实际需要,移除了原生的snapshot过程。同时放弃原生的日志文件部分WAL,而改用自研方案。 为什么移除snapshot呢?原来在Raft的流程中,为了防止Raft日志的无限增加,会每隔一段时间做snapshot,早于snapshot index的Raft日志请求,将直接用snapshot回应。然而我们的单Raft环架构如果要做snapshot,就是对整个InfluxDB做,将非常消耗资源和影响性能,而且过程中要锁死整个InfluxDB,这都是不能让人接受的。所以我们暂时不启用snapshot功能,而是存储固定数量的、较多的Raft日志文件备用。 自研的Raft日志文件模块会周期清理最早的日志防止磁盘开销过大,当某个节点下线的时间并不过长时,其他正常节点上存储的日志文件如果充足,则足够满足它追取落后的数据。但如果真的发生单节点宕机太长,正常节点的日志文件已出现被清理而不足故障节点追取数据时,我们将利用InfluxDB的backup和restore工具,将落后节点还原至被Raft日志涵盖的较新的状态,然后再做追取。 在我们的场景下,ETCD自身的WAL模块并不适用于InfluxDB。ETCD的WAL是纯追加模式的,当故障恢复时,正常节点要相应落后节点的日志请求时,就有必要分析并提取出相同index且不同term中那条最新的日志,同时InfluxDB的一条entry可能包含超过20M的时序数据,这对于非kv模式的时序数据库而言是非常大的磁盘开销。 HybridStorage设计我们自研的Raft日志模块命名为HybridStorage,即意为内存与文件混合存取,内存保留最新热数据,文件保证全部日志落盘,内存、文件追加操作高度一致。 HybridStorage的设计思路是这样的: (1)保留MemoryStorage:为了保持热数据的读取效率,内存中的MemoryStorage会保留作为热数据cache提升性能,但是周期清理其中最早的数据,防止内存消耗过大。 (2)重新设计WAL:WAL不再是像ETCD那样的纯追加模式、也不需要引入类似RocksDB这样重的读写引擎。新增的日志在MemoryStorage与WAL都会保存,WAL文件中最新内容始终与MemoryStorage保持完全一致。 一般情况下,HybridStorage新增不同index的日志条目时,需要在写内存日志时同时操作文件执行类似的增减。正常写入流程如下图所示: 当出现了同index不同term的日志条目的情况,此时执行truncate操作,截断对应文件位置之后一直到文件尾部的全部日志,然后重新用append方式写入最新term编号的日志,操作逻辑上十分清晰,不存在Update文件中间的某个位置的操作。 例如在一组Raft日志执行append操作时,出现了如下图所示的同index(37、38、39)不同term的日志条目的情况。在MemoryStorage的处理方式是:找到对应index位置的内存位置(内存位置37),并抛弃从位置A以后的全部旧日志占用的内存数据(因为在Raft机制中,这种情况下内存位置37以后的那些旧日志都是无效的,无需保留),然后拼接上本次append操作的全部新日志。在自研WAL也需要执行类似的操作,找到WAL文件中对应index的位置(文件位置37),删除从文件位置37之后的所有文件内容,并写入最新的日志。如下图分析: 方案对比ETCD的方案,Raft日志有2个部分,文件与内存,文件部分因为只有追加模式,因此并不是每一条日志都是有效的,当出现同index不同term的日志条目时,只有最新的term之后的日志是生效的。配合snapshot机制,非常适合ETCD这样的kv存储系统。但对于InfluxDB高可用版本而言,snapshot将非常消耗资源和影响性能,而且过程中要锁死整个InfluxDB。同时,一次Raft流程的一条entry可能包含超过20M的时序数据。所以这种方案不适合。 CockroachDB的方案,看似偷懒使用了RocksDB的能力,但因其底层存储引擎也是RocksDB,所以无何厚非。但对于我们这样需要Raft一致性协议的时序数据库而言,引入RocksDB未免过重了。 自研的Raft HybridStorage是比较符合阿里云InfluxDB®的场景的,本身模块设计轻便简介,内存保留了热数据缓存,文件使用接近ETCD append only的方式,遇到同index不同term的日志条目时执行truncate操作,删除冗余与无效数据,降低了磁盘压力。 总结本文对比了业内常见的两种Raft日志的实现方案,也展示了阿里云InfluxDB®团队自研的HybridStorage方案。在后续开发过程中,团队内还会对自研Raft HybridStorage进行多项优化,例如异步写、日志文件索引、读取逻辑优化等等。也欢迎读者提出自己的解决方案。相信阿里云InfluxDB®团队在技术积累与沉淀方面会越做越好,成为时序数据库技术领导者。 本文作者:德施阅读原文 本文为云栖社区原创内容,未经允许不得转载。

July 11, 2019 · 1 min · jiezi

Redis-Cluster节点故障探测算法笔记

本笔记是对Redis Cluster Spec - Failure Detection的归纳总结 状态转换图每个Node在本地维护了一张其他Node的状态表,并根据Failure Detection算法更新这张表里的Node的状态每个Node可以自行把其他Node的状态设置为GOOD(这个状态在文档和源码中均不存在,等价于不是PFAIL也不是FAIL)、PFAIL。如果要把其他Node的状态设置为FAIL则需要大多数Master Node同意才行,一旦设置成功要将这个消息传播给所有其他能连接的Node,其他Node收到这个信息后也要更新本地Node状态表,将Failed Node的状态更新为FAIL。下面是状态转换图,例举的是Node A观察Node B的例子: 少数派和多数派多数派:拥有多数Master的一方,可含有Slave。 少数派:拥有少数Master的一方,可含有Slave。 少数派视角少数派只会看到大多数Master处于PFAIL/FAIL状态,0-所有Slave处于PFAIL/FAIL状态。 多数派视角多数派只会看到少数Master处于PFAIL/FAIL状态,0-所有Slave处于PFAIL/FAIL状态。 不会存在以下情况:多数派看到大多数Master处于FAIL状态,因为大多数Master处于FAIL就意味着活着的Master们变成了少数派,这就矛盾了。 一些自问自答Q:为何少数派能够看到Master处于FAIL状态?不是说要大多数Master同意才能变成FAIL状态吗?A:考虑这个情况,在Partition发生的前一秒某些Master被决定为FAIL,随即Partition发生,那么在少数派眼里这些Master依然是处于FAIL状态的。 Q:这里的每个Node是Slave还是Master呢?A:随便,只要是Node就行。 Q:既然每个Master独占的负责Slots,那么少数派继续工作为啥不可以,反正各自管各自的。A:因为在多数派方,这个Master有可能会被Slave顶替,如果允许少数派继续工作,那么就会形成两个Master,造成split brain Q:少数派节点是如何知道自己应该停止工作的?A:它发现大多数Master变成了PFAIL / FAIL 状态时,就知道自己不能工作了,Redis源码里是这么写的。 Q:多数派节点时如何知道自己应该停止工作的?A:如果这个Cluster要求所有Slots被覆盖,那么当有一个Master处于FAIL状态时,便停止工作,见源码。如果不要求,则继续工作,只不过部分Slots的操作会报错。

July 10, 2019 · 1 min · jiezi

运维编排场景系列给实例加到SLS机器组

场景简介我们经常会有这样的运维场景,扩容一批机器需要配置SLS日志,对于已经配置好的SLS Logstore后,我们只需要将机器加到机器组里。 解决方案传统的解决方案是登录每台ecs实例并安装logtail,执行的命令为 wget http://logtail-release-{{ACS::RegionId}}.oss-{{ACS::RegionId}}-internal.aliyuncs.com/linux64/logtail.sh -O logtail.sh; chmod 755 logtail.sh; ./logtail.sh install {{ACS::RegionId}};echo {{ LogTailUserDefinedId }} > /etc/ilogtail/user_defined_id分解下Task,需要以下几步:1.检查实例是不是Running状态2.调用云助手CreateCommand创建上述命令3.调用InvokeCommand执行4.等待执行成功5.删除模板 再转换成OOS模板并创建命名为installSlsAgent { "FormatVersion": "OOS-2019-06-01", "Description": "Install Logtail agent on the ECS Instance.", "Parameters": { "InstanceId": { "Type": "String", "Description": "the Instance Id to install ilogtail", "AllowedPattern": "i-[A-Za-z0-9]*", "MinLength": 1, "MaxLength": 30 }, "LogTailUserDefinedId": { "Type": "String", "Description": "the user defined Id write to /etc/ilogtail/user_defined_id", "AllowedPattern": "[A-Za-z0-9\\-_]*", "MinLength": 1, "MaxLength": 30 }, "OOSAssumeRole": { "Type": "String", "Description": "The RAM role to be assumed by OOS.", "Default": "OOSServiceRole" } }, "RamRole": "{{OOSAssumeRole}}", "Tasks": [ { "Name": "checkInstanceReady", "Action": "ACS::CheckFor", "Description": "describe instances with specified parameters, refer them here: https://help.aliyun.com/document_detail/63440.html", "Properties": { "API": "DescribeInstances", "Service": "ECS", "PropertySelector": "Instances.Instance[].Status", "DesiredValues": [ "Running" ], "Parameters": { "InstanceIds": [ "{{ InstanceId }}" ] } }, "Outputs": { "InstanceIds": { "ValueSelector": "InstanceIdSets.InstanceIdSet[]", "Type": "List" } } }, { "Name": "createCommand", "Action": "ACS::ExecuteApi", "Description": "create the command to install logtail agent.", "Properties": { "API": "CreateCommand", "Service": "ECS", "Parameters": { "CommandContent": { "Fn::Base64Encode": "wget http://logtail-release-{{ACS::RegionId}}.oss-{{ACS::RegionId}}-internal.aliyuncs.com/linux64/logtail.sh -O logtail.sh; chmod 755 logtail.sh; ./logtail.sh install {{ACS::RegionId}}; echo {{ LogTailUserDefinedId }} > /etc/ilogtail/user_defined_id" }, "Name": "oos-{{ACS::TemplateName}}", "Type": "RunShellScript" } }, "Outputs": { "CommandId": { "Type": "String", "ValueSelector": "CommandId" } } }, { "Name": "invokeCommand", "Action": "ACS::ExecuteApi", "Description": "invoke the command to install ilogtail", "Properties": { "Service": "ECS", "API": "InvokeCommand", "Parameters": { "CommandId": "{{ createCommand.CommandId }}", "InstanceIds": [ "{{ InstanceId }}" ] } }, "Outputs": { "InvokeId": { "Type": "String", "ValueSelector": "InvokeId" } } }, { "Name": "untilInvocationDone", "Action": "ACS::WaitFor", "Description": "until invocation ready", "MaxAttempts": 5, "Properties": { "Service": "ECS", "API": "DescribeInvocations", "Parameters": { "InvokeId": "{{ invokeCommand.InvokeId }}" }, "DesiredValues": [ "Finished" ], "PropertySelector": "Invocations.Invocation[].InvokeStatus" } }, { "Name": "describeInvocationResult", "Action": "ACS::ExecuteApi", "Description": "get the command invocation result", "Properties": { "Service": "Ecs", "API": "DescribeInvocationResults", "Parameters": { "InvokeId": "{{ invokeCommand.InvokeId }}" } }, "Outputs": { "InvocationResult": { "Type": "String", "ValueSelector": "Invocation.InvocationResults.InvocationResult[].Output" }, "ExitCode": { "Type": "Number", "ValueSelector": "Invocation.InvocationResults.InvocationResult[].ExitCode" } } }, { "Name": "deleteCommand", "Action": "ACS::ExecuteAPI", "Description": "clean up the install ilogtail command", "Properties": { "Service": "ECS", "Risk": "Normal", "API": "DeleteCommand", "Parameters": { "CommandId": "{{ createCommand.CommandId }}" } } } ], "Outputs": { "InvocationResult": { "Type": "String", "Value": { "Fn::Base64Decode": "{{ describeInvocationResult.InvocationResult }}" } }, "ExitCode": { "Type": "String", "Value": "{{ describeInvocationResult.ExitCode }}" } }}以上模板我们很好的解决了单台机器执行Install sls Agent的任务,那么对于多台机器的执行怎么办呢?OOS的Loop功能可以很好的解决这个问题。并且OOS支持模板嵌套执行,那么我们只需要构建一个传入实例ID列表的 ...

July 9, 2019 · 3 min · jiezi

分布式主动感知在智能运维中的实践分享实录

导读:企业数字化使得运维智能化转型成为必然,宜信积极推动 AIOps 在科技金融企业的落地实践。本次主题是探索 AIOps 落地的一种形式:通过行为采集、仿真模拟、主动感知等手段,从用户侧真实系统使用体验出发,结合全维监控数据,更加有效的实现智能异常检测和根因分析。 一、运维的发展1.1 运维的价值早期的运维工作比较简单,一般是先由系统集成工程师及研发工程师研发完项目后交付出来,再由负责运维工作的人员从后台做一些操作,保证系统正常运行。 图1 随着软件研发行业和技术的发展,运维的工作也变得越来越丰富。现阶段运维的工作与价值主要集中在三个方面: 1)效率大量业务上线,运维人员需要保障快速高效地为系统提供资源、应对业务变更、响应操作请求。 2)质量运维的目标是保障质量及系统的稳定性。也就是说,要保障业务和系统7*24小时在线上稳定运行,为用户提供流畅舒适的体验。为实现这个目标,运维的相关工作包括: 故障预测:没出现问题之前预测到故障发生的可能。异常检测:出现问题时很快检测并定位到异常点。根因分析:分析问题的诱因,找出真正导致问题的根本原因。动态扩容:问题处理的过程中可能受到复杂因素的影响,需要对系统进行动态扩容。服务降级:不影响核心业务的边缘业务可能需要做服务降级处理。3)成本随着公司规模的不断壮大,投入产出比也越来越被重视。运维的另外一个价值在于降低成本。主要体现为: 容量规划:规划每年在IT运维层面投入多少人员和资源。弹性调度:如何调度和分配资源,实现资源的充分利用。利用率分析:利用率分析包括动态和静态两个方面。趋势分析:比如今年花了多少钱在IT运维层面,明年要花多少钱在这个方面,这是一个趋势分析。成本分析:成本分析包括今年有多少业务、每个业务用了多少钱、多少IT技术设施、多少人员。1.2 运维的困境 图2 如图所示,横坐标代表服务规模。公司业务不断增长,服务规模也相应增长,此处我们简单理解为这是一个线性的变化,不考虑业务的暴增。 然而,业务规模增长反映到运维的复杂度增长上最少体现在三个层面: 服务规模的增长直接导致服务器量及网络量的增长,随之而来的是网络拓扑的增长。业务增长,服务的技术栈也是增长的。以前可能前边跑一个服务,后边跑一个数据库就可以了,现在随着服务规模的不断增长,引入不同服务形式,可能就有了队列、缓存等,相应的,技术栈也不断增加。服务拓扑不断增长。以前可能一个烟囱型的服务就可以了,而现在随着微服务的应用,服务之间的调度非常多,需要增长服务拓扑来满足需求。随着服务规模的增长,运维复杂度呈现指数级增长,那运维人员是否也随着增长了呢?纵观各司,答案是否定的。出于节约成本的考虑,各司各岗位人员并不会随着服务复杂度增加而扩张,反而是越来越趋于平稳。基于这个比例,相当于运维复杂度越来越高的情况下,运维人员越来越少了。 中间的差距如何来弥补呢?这就需要运用到运维手段了。即上图所示的:运维质量=运维人员 X 运维手段。运维人员要通过各种运维手段来解决运维困境,进而推动运维的发展。 1.3 运维的发展图3 如图所示,运维的发展大致分为四个阶段: 1)手工阶段手工阶段比较好理解,研发人员交付一个系统,运维人员通过手工执行操作保障这个系统正常运行。此阶段的运维工作没有什么标准可言。 2)标准化阶段随着企业IT系统越来越多地引入运维,且所有业务都变成系统形式在线上运行,运维工作的重要性越来越高,但同时带来的是运维和研发、业务人员工作中的沟通壁垒。这时就衍生出了一些标准,其中最主要的是ITSM(IT Service Management,IT服务管理)。ITSM的目标是把日常所有的运维工作,包括流程、信息管理、风险控制等,通过系统建设和标准化固定下来,像流水线一样,人员只需要按照标准参与即可。 3)自动化阶段随着互联网大爆发,服务交付模型越来越多,用户对互联网和IT的要求越来越高,ITSM的缺点也越来越明显,主要表现为时间过长、成本过高,不能适应快速多变的需求。于是从工程或运维的角度自发出现了一种文化:DevOps,DevOps强调运维、研发及QA工程师工作的高度融合,要求运维从工程交付的角度不断迭代。 同时从企业IT管理或运营诉求出发也要解决快速演进的问题,于是演化出了标准ITOM。ITOM和ITSM很像,区别是把“S”改成“O”,即把Operation本身及其带来的各种自动化工具纳入模型中,包括主机、运营、发布系统等等。 DevOps不断发展演变成现在的ChatOps,ChatOps的目标是将研发、运维、QA融合起来,以说话(Chat)的方式进行交流,但 ChatOps 只考虑了交流的形式,并没有就如何实现基于 Chat 方式的整体解决方案,ChatOps 并没有很好的解决 DevOps 的困境。ITOM把所有的Operation线上化、自动化后,发现IT运维所产生的大量数据是非常有意义的,特别是对于企业数字化而言,这些数据经过加工分析,可以对日常业务产生价值。于是Gartner提出了一个新的标准“ITOA”。ITOA强调IT数据的价值,提出对IT运维分析的诉求,但没说明这个数据能干什么。很快Gartner就将ITOA演化成“AIOps”。这时AIOps中的“AI”是指“Algorithm(算法)”,强调的是数据分析本身产生的价值,包括通过算法来解决线上故障发现、日常交互等运维问题。4)智能化阶段随着行业对IT运维要求的不断提高,无论是AIOps还是ChatOps,都面临一个严重的问题:人处理不过来了。从工程角度来看,运维面临的现状是异构性非常强,需要引入三方应用和各种各样的设备,交付模式也越来越多,运维复杂度出现指数级增长。为解决上述问题,Gartner适时提出了“AIOps”的概念,这里的“AI”代表的是人工智能,通过机器人的参与将人工智能技术体系带入到运维的各个环节,帮助解决运维问题,运维发展也由此进入智能化阶段。 二、什么是智能运维2.1 什么是智能运维(AIOps)?图4 BMC给了AIOps定义是: AIOps refers to multi-layered technology platforms that automate and enhance IT operations by 1) using analytics and machine learning to analyze big data collected from various IT operations tools and devices, in order to 2) automatically spot and react to issues in real time.简单来说,就是引入多层平台,使用大数据分析和机器学习等方法,加强IT运维自动化的能力。 ...

July 9, 2019 · 2 min · jiezi

分布式服务架构下的混沌工程实践

本文来自阿里巴巴高可用架构团队高级开发工程师肖长军(花名穹谷)在 GIAC(全球互联网架构大会)上的分享,包含三部分内容:(阿里巴巴中间件公众号对话框发送“混沌工程”,获取分享PPT) 混沌工程的定义、价值、原则和流程;混沌工程如何在企业中落地,以及 ChaosBlade 和混沌实验平台 AHAS Chaos 架构设计;结合两个具体案例介绍了分布式服务下的混沌工程实践;大家好,我是来自阿里的肖长军,今天给大家分享混沌工程在分布式服务架构下的具体实践。 先做个自我介绍,我来自于阿里高可用架构团队,花名穹谷,做过分布式系统设计和 APM 研发相关工作,现在专注于高可用架构和混沌工程领域,是阿里云产品 AHAS 底层技术负责人和开源项目 ChaosBlade 负责人,并且承担集团内故障演练、突袭演练、攻防演练相关的研发工作。今天分享的内容包含以下三个方面。 先从混沌工程的定义、价值、原则和实施步骤介绍混沌工程,然后分享混沌工程如何在企业中落地,最后介绍分布式服务下混沌工程实践案例。我们先来看一下什么是混沌工程。 混沌工程理论一文中提到,其是在分布式系统上进行实验的学科,核心目的是提高生产环境中系统的容错性和可恢复性。尼采的这句话: "打不倒我的必使我强大",也很好的诠释了混沌工程反脆弱的思想。除了这里提到的目的,实施混沌工程还有哪些价值呢? 这里我从四个角色来说明,对于架构师来说,可以验证系统架构的容错能力,比如验证现在提倡的面向失败设计的系统;对于开发和运维,可以提高故障的应急效率,实现故障告警、定位、恢复的有效和高效性。对于测试来说,可以弥补传统测试方法留下的空白,之前的测试方法基本上是从用户的角度去做,而混沌工程是从系统的角度进行测试,降低故障复发率。对于产品和设计,通过混沌事件查看产品的表现,提升客户使用体验。所以说混沌工程面向的不仅仅是开发、测试,拥有最好的客户体验是每个人的目标。我们知道,系统发生故障的那一刻不是由你来选择的,而是那一刻选择你,你所能做,只能是为之做好准备。了解了混沌工程的价值,我们再来看一下实施混沌工程的一些原则。 前面 Vilas 老师也提到了,我这里重点来介绍一下这五项原则。第一条:”建立一个围绕稳定状态行为的假说“,其包含两个含义,一个是定义能直接反应业务服务的监控指标,需要注意的是这里的监控指标并不是系统资源指标,比如CPU、内存等,这里的监控指标是能直接衡量系统服务质量的业务监控。举个例子,一个调用延迟故障,请求的 RT 会变长,对上层交易量造成下跌的影响,那么这里交易量就可以作为一个监控指标。这条原则的另一个含义是故障触发时,对系统行为作出假设以及监控指标的预期变化。第二个指模拟生产环境中真实的或有理论依据的故障,第三个建议在生产环境中运行实验,但也不是说必须在生产环境中执行,只是实验环境越真实,混沌工程越有价值。持续的执行才能持续的降低故障复发率和提前发现故障,所以需要持续的自动化运行试验,最后一个,混沌工程很重要的一点是控制爆炸半径,也就是试验影响面,防止预期外的资损发生,后面会介绍控制爆炸半径的方式。依据这些指导原则可以更有效实施混沌工程,那么混沌工程的实施步骤是什么? 主要细分为这 8 步,指定试验计划,定义稳态指标,做出系统容错假设,执行实验,检查稳态指标,记录、恢复 实验,修复发现的问题,然后做持续验证。以上是对混沌工程理论相关的介绍,那么如何在企业中落地混沌工程呢? 我这里分为三个阶段,首先要坚定价值,因为你会受到来自多方面的挑战,其次引入混沌工程技术,最后在企业中推广混沌工程文化。在实施混沌工程之前,必须能说清楚混沌工程的价值,而且当受到挑战时,意志要坚定。 比如来自老板的挑战,”如何衡量混沌工程的价值?“,可以向老板表达出,”从故障的应急效率、故障复发率、线上故障发现数来衡量“等等。所以这些问题自己要想清楚。有了坚定的意志,就要开始落地,首先要先了解自己的系统。 这里系统成熟度分 5 个等级,也可以说是业务系统所处的阶段,列出了每个阶段适合什么故障场景。刚才也有听众问,”我的服务就是单点的,还有没有实施混沌工程的必要?“,有必要,可以实施简单的实验场景,比如 CPU 满载等,来验证监控告警,如果发现没有监控告警,就要去推动完善它,然后再推动服务多实例部署,通过混沌工程一级一级的去推动系统的演进,最终实现具有韧性的系统。根据系统成熟度了解自己系统所适合的场景,接下来就要选择一款合适的混沌实验工具。 这里列举了五个维度:场景丰富度、工具类型、易用性等。可以从 awesome-chaos-engineering github 项目查找或者从 CNCF Landscpage 中查看混沌实验工具。阿里今年开源的 ChaosBlade 也已经加入到 CNCF Landscape 中,后面会对此项目做重点介绍,先来看阿里混沌工程技术的演进。 2012 年阿里内部就上线了 EOS 项目,用于梳理分布式服务强弱依赖问题,同年进行了同城容灾的断网演练。 15 年 实现异地多活,16 年内部推出故障演练平台 MonkeyKing,开始在线上环境实施混沌实验,然后 18 年输出了 ACP 专有云产品 和 AHAS 公有云产品,其中 AHAS 旨在将阿里的高可用架构经验以产品的形式对外输出,服务于外部。19 年推出 ChaosBlade 项目,将底层的故障注入能力对外开源,同年也推出混沌实验平台专有云版本 AHAS Chaos,接下来重点介绍一下 ChaosBlade 项目。 ...

July 5, 2019 · 1 min · jiezi

如何带领团队攻城略地优秀的架构师这样做

阿里妹导读:架构师是一个既能掌控整体又能洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物。看似完美的“人格模型”背后,是艰辛的探索。今天,阿里巴巴技术专家九摩将多年经验,进行系统性地总结,帮助更多架构师在进阶这条路上走得更“顺畅”,姿态更“优雅”。架构师职责架构师不是一个人,他需要建立高效卓越的体系,带领团队去攻城略地,在规定的时间内完成项目。 架构师需要能够识别定义并确认需求,能够进行系统分解形成整体架构,能够正确地技术选型,能够制定技术规格说明并有效推动实施落地。 按 TOGAF 的定义,架构师的职责是了解并关注实际上关系重大但未变得过载的一些关键细节和界面,架构师的角色有:理解并解析需求,创建有用的模型,确认、细化并扩展模型,管理架构。 从业界来看对于架构师的理解可以大概区分为: 企业架构师:专注于企业总体 IT 架构的设计。IT 架构师-软件产品架构师:专注于软件产品的研发。IT 架构师-应用架构师:专注于结合企业需求,定制化 IT 解决方案;大部分需要交付的工作包括总体架构、应用架构、数据架构,甚至部署架构。IT 架构师-技术架构师:专注于基础设施,某种软硬件体系,甚至云平台,提交:产品建议、产品选型、部署架构、网络方案,甚至数据中心建设方案等。阿里内部没有在职位 title 上专门设置架构师了,架构师更多是以角色而存在,现在还留下可见的 title 有两个:首席架构师和解决方案架构师,其中解决方案架构师目前在大部分 BU 都有设置,特别是在阿里云和电商体系。 解决方案架构师 工作方式理解 了解和挖掘客户痛点,项目定义,现有环境管理;梳理明确高阶需求和非功能性需求;客户有什么资产,星环(阿里电商操作系统)/阿里云等有什么解决方案;沟通,方案建议,多次迭代,交付总体架构;架构决策。职责 1.从客户视图来看: 坚定客户高层信心:利用架构和解决方案能力,帮忙客户选择星环/阿里云平台的信心。解决客户中层问题:利用星环/阿里云平台服务+结合应用架构设计/解决方案能力,帮忙客户解决业务问题,获得业务价值。引领客户 IT 员工和阿里生态同学:技术引领、方法引领、产品引领。2.从项目视图看: 对接管理部门:汇报技术方案,进度;技术沟通。对接客户 PM,项目 PM:协助项目计划,人员管理等。负责所有技术交付物的指导。对接业务部门和需求人员:了解和挖掘痛点,帮忙梳理高级业务需求,指导需求工艺。对接开发:产品支持、技术指导、架构指导。对接测试:配合测试计划和工艺制定。配合性能测试或者非功能性测试。对接运维:产品支持,运维支持。对接配置&环境:产品支持。其他:阿里技术资源聚合。3.从阿里内部看: 销售方案支持;市场宣贯;客户需求Facade;解决方案沉淀。架构师职责明确了,那么有什么架构思维可以指导架构设计呢?请看下述的架构思维。 架构思维自顶向下构建架构 要点主要如下: 1.首先定义问题,而定义问题中最重要的是定义客户的问题。定义问题,特别是识别出关键问题,关键问题是对客户有体感,能够解决客户痛点,通过一定的数据化来衡量识别出来,关键问题要优先给出解决方案。 2.问题定义务必加入时间维度,把手段/方案和问题定义区分开来。 3.问题定义中,需要对问题进行升层思考后再进行升维思考,从而真正抓到问题的本质,理清和挖掘清楚需求;要善用第一性原理思维进行分析思考问题。 4.问题解决原则:先解决客户的问题(使命),然后才能解决自己的问题(愿景);务必记住不是强调我们怎么样,而是我们能为客户具体解决什么问题,然后才是我们变成什么,从而怎么样去更好得服务客户。 5.善用多种方法对客户问题进行分析,转换成我们产品或者平台需要提供的能力,比如仓储系统 WMS 可以提供哪些商业能力。 6.对我们的现有的流程和能力模型进行梳理,找到需要提升的地方,升层思考和升维思考真正明确提升部分。 7.定义指标,并能够对指标进行拆解,然后进行数学建模。 8.将抽象出来的能力诉求转换成技术挑战,此步对于技术人员来说相当于找到了靶子,可以进行方案的设计了,需要结合自底向上的架构推导方式。 9.创新可以是业务创新,也可以是产品创新,也可以是技术创新,也可以是运营创新,升层思考、升维思考,使用第一性原理思维、生物学(进化论--进化=变异+选择+隔离、熵增定律、分形和涌现)思维等哲科思维可以帮助我们在业务,产品,技术上发现不同的创新可能。可以说哲科思维是架构师的灵魂思维。 自底向上推导应用架构 先根据业务流程,分解出系统时序图,根据时序图开始对模块进行归纳,从而得到粒度更大的模块,模块的组合/聚合构建整个系统架构。 基本上应用逻辑架构的推导有4个子路径,他们分别是: 业务概念架构:业务概念架构来自于业务概念模型和业务流程;系统模型:来自于业务概念模型;系统流程:来自业务流程;非功能性的系统支撑:来自对性能、稳定性、成本的需要。效率、稳定性、性能是最影响逻辑架构落地成物理架构的三大主要因素,所以从逻辑架构到物理架构,一定需要先对效率、稳定性和性能做出明确的量化要求。 自底向上重度依赖于演绎和归纳。 如果是产品方案已经明确,程序员需要理解这个业务需求,并根据产品方案推导出架构,此时一般使用自底向上的方法,而领域建模就是这种自底向上的分析方法。 对于自底向上的分析方法,如果提炼一下关键词,会得到如下两个关键词: 1.演绎:演绎就是逻辑推导,越是底层的,越需要演绎: 从用例到业务模型就属于演绎;从业务模型到系统模型也属于演绎;根据目前的问题,推导出要实施某种稳定性措施,这是也是演绎。2.归纳:这里的归纳是根据事物的某个维度来进行归类,越是高层的,越需要归纳: 问题空间模块划分属于归纳;逻辑架构中有部分也属于归纳;根据一堆稳定性问题,归纳出,事前,事中,事后都需要做对应的操作,是就是根据时间维度来进行归纳。 领域驱动设计架构 大部分传统架构都是基于领域模型分析架构,典型的领域实现模型设计可以参考DDD(领域驱动设计),详细可以参考《实现领域驱动设计》这本书,另外《UML和模式应用》在领域建模实操方面比较好,前者偏理论了解,后者便于落地实践。 领域划分设计步骤: 1.对用户需求场景分析,识别出业务全维度 Use Case; 2.分析模型鲁棒图,识别出业务场景中所有的实体对象。鲁棒图 —— 是需求设计过程中使用的一种方法(鲁棒性分析),通过鲁棒分析法可以让设计人员更清晰,更全面地了解需求。它通常使用在需求分析后及需求设计前做软件架构分析之用,它主要注重于功能需求的设计分析工作。需求规格说明书为其输入信息,设计模型为其输出信息。它是从功能需求向设计方案过渡的第一步,重点是识别组成软件系统的高级职责模块、规划模块之间的关系。鲁棒图包含三种图形:边界、控制、实体,三个图形如下: ...

July 4, 2019 · 3 min · jiezi

蚂蚁金服胡喜金融服务将成为开源的下个前沿领域

近日,全球知名开源组织云原生计算基金会 CNCF 宣布,蚂蚁金服正式成为 CNCF 黄金会员。为什么蚂蚁金服会拥抱开源,科技公司和开源社区如何实现双赢且可持续发展?蚂蚁金服副CTO胡喜在TechCrunch上发表专栏阐述了自己的见解。 自诞生以来,开源软件在许多行业有效地推动了技术普及、开放与公平竞争。然而,金融服务业一直是个罕见的例外:金融机构依然倾向于使用私有技术进行开发和运营。 传统上,金融服务业只为少数人提供服务。全球有 20 亿人和 2 亿小微企业无法获得银行和信贷等基本服务。在这样的情况下,开源技术可能会是推动普惠金融的关键。 Gartner 报告称,在汇率不变情况下,银行和证券业的 IT 支出 2018 年增长了 4.6%。银行和证券公司仍坚定不移地将数字化转型放在未来发展的首要位置。不过在很大程度上,有能力与资源投入技术开发的主要是全球性的大银行,规模较小的地区性银行则没有这样的机会。 小银行,例如来自发展中国家和农村地区的银行往往缺乏专业技术知识,也难以承担当代信息技术系统,例如下一代数据库、先进的分布式计算架构和金融级人工智能的建设成本。但是,如果这些机构愿意利用集众人之力、低成本的开源创新,那么就可以更好地服务它们的市场。 金融科技开源基金会(FINOS)的成立是朝着这个方向迈出的重要一步。该基金会的成员包括美国资产管理规模最大 30 家银行中的 10 家,例如高盛和摩根大通。 出于同样的原因,蚂蚁金服加入了云原生计算基金会(CNCF),成为黄金会员。位于硅谷的 CNCF 管理着云原生软件体系的关键部分,包括 Kubernetes 和 Prometheus,也是 Linux 基金会旗下领先的开源组织。通过与 CNCF 及其旗下成员分享我们的技术知识,支付宝致力于向全球金融机构和合作伙伴开放我们的技术,同时与中国的地区性和农村地区银行合作,基于成熟的开源技术提供产品,助力它们的数字化转型。 成立于 2004 年的支付宝在中国开创了安全可靠的支付系统。自那时以来,支付宝不断发展,为数百万小微企业提供各类服务,包括支付,小额信贷和保险等等。 我们正在给行业提供技术帮助,为 200 多家金融机构提高效率、降低成本。这些机构包括中国全国范围内的 100 多家银行、60 多家保险公司,以及 40 多家基金公司和证券公司。 借助过去多年服务支付宝这种任务关键型金融应用的经验,蚂蚁金服启动了多个开源项目,例如热门 UI 设计语言 Ant Design,以及 SOFAStack。后者在帮助用户顺利参加“双 11”活动的过程中发挥了关键作用。按交易量来看,“双 11”是全球最大的购物节。 利用 SOFAStack,各种规模的企业都可以轻松实现类似支付宝的规模和可靠性,在购物高峰期将关注重点转向如何更好地给顾客提供服务。 通过 SOFAStack 的开源,我们已经帮助南京银行等合作伙伴建设强大的技术系统。在 SOFAStack 和支付宝其他开源技术的帮助下,南京银行最近为自己和第三方合作伙伴开发了下一代核心银行系统“鑫云+”。 鑫云+带来了强大的性能,灵活的可扩展性,强数据一致性和重要的容灾机制。截止 2018 年底,鑫云+签约了近 1000 万新客户,日贷款申请处理能力上升了 10 倍,从 10 万笔提升至 100 万笔。贷款审核流程也因此加快,一些客户不到 1 秒就能获得贷款审批。同时,单账户的管理成本下降了 80% 至 90%。 ...

July 4, 2019 · 1 min · jiezi

蚂蚁金服大规模分布式事务实践和开源详解-GIAC-实录

本文整理自蚂蚁金服技术专家、分布式事务 Seata 发起者之一张森(花名:绍辉)在 GIAC 全球互联网架构大会的分享。详细讲解了在分布式架构演进中,蚂蚁金服面对的跨服务、跨数据库的业务数据一致性问题以及应对措施,并分享了分布式事务 Seata 的 AT、TCC、Saga 和 XA 四种模式。 Seata:https://github.com/seata/seata 一、自研分布式事务解决数据一致性问题1.1 分布式事务问题产生原因1.1.1 数据库的水平拆分蚂蚁金服的业务数据库起初是单库单表,但随着业务数据规模的快速发展,数据量越来越大,单库单表逐渐成为瓶颈。所以我们对数据库进行了水平拆分,将原单库单表拆分成数据库分片。 如下图所示,分库分表之后,原来在一个数据库上就能完成的写操作,可能就会跨多个数据库,这就产生了跨数据库事务问题。 1.1.2 业务服务化拆分在业务发展初期,“一块大饼”的单业务系统架构,能满足基本的业务需求。但是随着业务的快速发展,系统的访问量和业务复杂程度都在快速增长,单系统架构逐渐成为业务发展瓶颈,解决业务系统的高耦合、可伸缩问题的需求越来越强烈。 如下图所示,蚂蚁金服按照面向服务(SOA)的架构的设计原则,将单业务系统拆分成多个业务系统,降低了各系统之间的耦合度,使不同的业务系统专注于自身业务,更有利于业务的发展和系统容量的伸缩。 业务系统按照服务拆分之后,一个完整的业务往往需要调用多个服务,如何保证多个服务间的数据一致性成为一个难题。 1.2 蚂蚁金服遇到的数据一致性问题在数据库水平拆分、服务垂直拆分之后,一个业务操作通常要跨多个数据库、服务才能完成。在分布式网络环境下,我们无法保障所有服务、数据库都百分百可用,一定会出现部分服务、数据库执行成功,另一部分执行失败的问题。 当出现部分业务操作成功、部分业务操作失败时,业务数据就会出现不一致。以金融业务中比较常见的“转账”场景为例: 如下图所示,在支付宝的“转账”操作中,要分别完成 4 个动作: 创建交易订单;创建支付订单;A 账户扣钱;B 账户加钱;而完成以上操作要分别访问 3 个服务和 4 个数据库。 在分布式环境下,肯定会出现部分操作成功、部分操作失败的问题,比如:A 账户的钱扣了,但是 B 账户的钱没加上,这就造成了资金损失,影响资金安全。 在金融业务场景下,我们必须保证“转账”的原子性,要么所有操作全部成功,要么全部失败,不允许出现部分成功部分失败的现象。 为了解决跨数据库、跨服务的业务数据一致性问题,蚂蚁金服自主研发了分布式事务中间件。 从 2007 年开始做分布式事务并支持双十一,至今已经有 12 年。 2013 年,蚂蚁金服开始做单元化改造,分布式事务也开始支持 LDC、异地多活和高可用容灾,解决了机房故障情况下服务快速恢复的问题。 2014 年,蚂蚁金服分布式事务中间件 DTX(Distributed Transaction-eXtended)开始通过蚂蚁金融云对外输出,我们发展了一大批的外部用户。在发展外部客户的过程中,外部客户表示愿意牺牲一部分性能(无蚂蚁的业务规模)以换取接入便利性和无侵入性。所以在 2015 年,我们开始做无侵入的事务解决方案:FMT 模式和 XA 模式。 蚂蚁金服分布式事务(Distributed Transaction-eXtended,简称 DTX)链接:https://tech.antfin.com/products/DTX 二、投入开源社区,共建开源分布式事务 Seata2.1 分布式事务 Seata 介绍Seata(Simple Extensible Autonomous Transaction Architecture,简单可扩展自治事务框架)是 2019 年 1 月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案。Seata 开源半年左右,目前已经有接近一万 star,社区非常活跃。我们热忱欢迎大家参与到 Seata 社区建设中,一同将 Seata 打造成开源分布式事务标杆产品。 ...

July 3, 2019 · 3 min · jiezi

Feed流系统设计总纲

简介差不多十年前,随着功能机的淘汰和智能机的普及,互联网开始进入移动互联网时代,最具代表性的产品就是微博、微信,以及后来的今日头条、快手等。这些移动化联网时代的新产品在过去几年间借着智能手机的风高速成长。 这些产品都是Feed流类型产品,由于Feed流一般是按照时间“从上往下流动”,非常适合在移动设备端浏览,最终这一类应用就脱颖而出,迅速抢占了上一代产品的市场空间。 Feed流是Feed + 流,Feed的本意是饲料,Feed流的本意就是有人一直在往一个地方投递新鲜的饲料,如果需要饲料,只需要盯着投递点就可以了,这样就能源源不断获取到新鲜的饲料。 在信息学里面,Feed其实是一个信息单元,比如一条朋友圈状态、一条微博、一条咨询或一条短视频等,所以Feed流就是不停更新的信息单元,只要关注某些发布者就能获取到源源不断的新鲜信息,我们的用户也就可以在移动设备上逐条去浏览这些信息单元。 当前最流行的Feed流产品有微博、微信朋友圈、头条的资讯推荐、快手抖音的视频推荐等,还有一些变种,比如私信、通知等,这些系统都是Feed流系统,接下来我们会介绍如何设计一个Feed流系统架构。 Feed流系统特点Feed流本质上是一个数据流,是将 “N个发布者的信息单元” 通过 “关注关系” 传送给 “M个接收者”。 Feed流系统是一个数据流系统,所以我们核心要看数据。从数据层面看,数据分为三类,分别是: 发布者的数据:发布者产生数据,然后数据需要按照发布者组织,需要根据发布者查到所有数据,比如微博的个人页面、朋友圈的个人相册等。关注关系:系统中个体间的关系,微博中是关注,是单向流,朋友圈是好友,是双向流。不管是单向还是双向,当发布者发布一条信息时,该条信息的流动永远是单向的。接收者的数据:从不同发布者那里获取到的数据,然后通过某种顺序(一般为时间)组织在一起,比如微博的首页、朋友圈首页等。这些数据具有时间热度属性,越新的数据越有价值,越新的数据就要排在最前面。针对这三类数据,我们可以有如下定义: 存储库:存储发布者的数据,永久保存。关注表:用户关系表,永久保存。同步库:存储接收者的时间热度数据,只需要保留最近一段时间的数据即可。设计Feed流系统时最核心的是确定清楚产品层面的定义,需要考虑的因素包括: 产品用户规模:用户规模在十万、千万、十亿级时,设计难度和侧重点会不同。关注关系(单向、双写):如果是双向,那么就不会有大V,否则会有大V存在。上述是选择数据存储系统最核心的几个考虑点,除此之外,还有一些需要考虑的:如何实现Meta和Feed内容搜索? 虽然Feed流系统本身可以不需要搜索,但是一个Feed流产品必须要有搜索,否则信息发现难度会加大,用户留存率会大幅下降。Feed流的顺序是时间还是其他分数,比如个人的喜好程度? 双向关系时由于关系很紧密,一定是按时间排序,就算一个关系很紧密的人发了一条空消息或者低价值消息,那我们也会需要关注了解的。单向关系时,那么可能就会存在大V,大V的粉丝数量理论极限就是整个系统的用户数,有一些产品会让所有用户都默认关注产品负责人,这种产品中,该负责人就是最大的大V,粉丝数就是用户规模。接下来,我们看看整个Feed流系统如何设计。Feed流系统设计上一节,我们提前思考了Feed流系统的几个关键点,接下来,在这一节,我们自顶向下来设计一个Feed流系统。 1. 产品定义第一步,我们首先需要定义产品,我们要做的产品是哪一种类型,常见的类型有: 微博类朋友圈类抖音类私信类接着,再详细看一下这几类产品的异同: 类型关注关系是否有大V时效性排序微博类单向有秒~分时间抖音类单向/无有秒~分推荐朋友圈类双向无秒时间私信类双向无秒时间上述对比中,只对比各类产品最核心、或者最根本特点,其他次要的不考虑。比如微博中互相关注后就是双向关注了,但是这个不是微博的立命之本,只是补充,无法撼动根本。 从上面表格可以看出来,主要分为两种区分: 关注关系是单向还是双向: 如果是单向,那么可能就会存在大V效应,同时时效性可以低一些,比如到分钟级别;如果是双向,那就是好友,好友的数量有限,那么就不会有大V,因为每个人的精力有限,他不可能主动加几千万的好友,这时候因为关系更精密,时效性要求会更高,需要都秒级别。排序是时间还是推荐: 用户对feed流最容易接受的就是时间,目前大部分都是时间。但是有一些场景,是从全网数据里面根据用户的喜好给用户推荐和用户喜好度最匹配的内容,这个时候就需要用推荐了,这种情况一般也会省略掉关注了,相对于关注了全网所有用户,比如抖音、头条等。确定了产品类型后,还需要继续确定的是系统设计目标:需要支持的最大用户数是多少?十万、百万、千万还是亿?用户数很少的时候,就比较简单,这里我们主要考虑 亿级用户 的情况,因为如果系统能支持亿级,那么其他量级也能支持。为了支持亿级规模的用户,主要子系统选型时需要考虑水平扩展能力以及一些子系统的可用性和可靠性了,因为系统大了后,任何一个子系统的不稳定都很容易波及整个系统。 2. 存储我们先来看看最重要的存储,不管是哪种同步模式,在存储上都是一样的,我们定义用户消息的存储为存储库。存储库主要满足三个需求: 可靠存储用户发送的消息,不能丢失。否则就找不到自己曾经发布到朋友圈状态了。读取某个人发布过的所有消息,比如个人主页等。数据永久保存。所以,存储库最重要的特征就是两点: 数据可靠、不丢失。由于数据要永久保存,数据会一直增长,所以要易于水平扩展。综上,可以选为存储库的系统大概有两类: 特点分布式NoSQL关系型数据库(分库分表)可靠性极高高水平扩展能力线性需要改造水平扩展速度毫秒无常见系统Tablestore、BigtableMySQL、PostgreSQL对于可靠性,分布式NoSQL的可靠性要高于关系型数据库,这个可能有违很多人的认知。主要是关系型数据库发展很长时间了,且很成熟了,数据放在上面大家放心,而分布式NoSQL数据库发展晚,使用的并不多,不太信任。但是,分布式NoSQL需要存储的数据量更多,对数据可靠性的要求也加严格,所以一般都是存储三份,可靠性会更高。目前在一些云厂商中的关系型数据库因为采用了和分布式NoSQL类似的方式,所以可靠性也得到了大幅提高。水平扩展能力:对于分布式NoSQL数据库,数据天然是分布在多台机器上,当一台机器上的数据量增大后,可以通过自动分裂两部分,然后将其中一半的数据迁移到另一台机器上去,这样就做到了线性扩展。而关系型数据库需要在扩容时再次分库分表。所以,结论是: 如果是自建系统,且不具备分布式NoSQL数据库运维能力,且数据规模不大,那么可以使用MySQL,这样可以撑一段时间。如果是基于云服务,那么就用分布式NoSQL,比如Tablestore或Bigtable。如果数据规模很大,那么也要用分布式NoSQL,否则就是走上一条不归路。如果使用Tablestore,那么存储库表设计结构如下: 主键列第一列主键第二列主键属性列属性列列名user_idmessage_idcontentother解释消息发送者用户ID消息顺序ID,可以使用timestamp。内容其他内容到此,我们确定了存储库的选型,那么系统架构的轮廓有了: 3. 同步系统规模和产品类型,以及存储系统确定后,我们可以确定同步方式,常见的方式有三种: 推模式(也叫写扩散):和名字一样,就是一种推的方式,发送者发送了一个消息后,立即将这个消息推送给接收者,但是接收者此时不一定在线,那么就需要有一个地方存储这个数据,这个存储的地方我们称为:同步库。推模式也叫写扩散的原因是,一个消息需要发送个多个粉丝,那么这条消息就会复制多份,写放大,所以也叫写扩散。这种模式下,对同步库的要求就是写入能力极强和稳定。读取的时候因为消息已经发到接收者的收件箱了,只需要读一次自己的收件箱即可,读请求的量极小,所以对读的QPS需求不大。归纳下,推模式中对同步库的要求只有一个:写入能力强。拉模式(也叫读扩散):这种是一种拉的方式,发送者发送了一条消息后,这条消息不会立即推送给粉丝,而是写入自己的发件箱,当粉丝上线后再去自己关注者的发件箱里面去读取,一条消息的写入只有一次,但是读取最多会和粉丝数一样,读会放大,所以也叫读扩散。拉模式的读写比例刚好和写扩散相反,那么对系统的要求是:读取能力强。另外这里还有一个误区,很多人在最开始设计feed流系统时,首先想到的是拉模式,因为这种和用户的使用体感是一样的,但是在系统设计上这种方式有不少痛点,最大的是每个粉丝需要记录自己上次读到了关注者的哪条消息,如果有1000个关注者,那么这个人需要记录1000个位置信息,这个量和关注量成正比的,远比用户数要大的多,这里要特别注意,虽然在产品前期数据量少的时候这种方式可以应付,但是量大了后就会事倍功半,得不偿失,切记切记。推拉结合模式:推模式在单向关系中,因为存在大V,那么一条消息可能会扩散几百万次,但是这些用户中可能有一半多是僵尸,永远不会上线,那么就存在资源浪费。而拉模式下,在系统架构上会很复杂,同时需要记录的位置信息是天量,不好解决,尤其是用户量多了后会成为第一个故障点。基于此,所以有了推拉结合模式,大部分用户的消息都是写扩散,只有大V是读扩散,这样既控制了资源浪费,又减少了系统设计复杂度。但是整体设计复杂度还是要比推模式复杂。用图表对比: 类型推模式拉模式推拉结合模式写放大高无中读放大无高中用户读取延时毫秒秒秒读写比例1:9999:1~50:50系统要求写能力强读能力强读写都适中常见系统Tablestore、Bigtable等LSM架构的分布式NoSQLRedis、memcache等缓存系统或搜索系统(推荐排序场景)两者结合架构复杂度简单复杂更复杂介绍完同步模式中所有场景和模式后,我们归纳下: 如果产品中是双向关系,那么就采用推模式。如果产品中是单向关系,且用户数少于1000万,那么也采用推模式,足够了。如果产品是单向关系,单用户数大于1000万,那么采用推拉结合模式,这时候可以从推模式演进过来,不需要额外重新推翻重做。永远不要只用拉模式。如果是一个初创企业,先用推模式,快速把系统设计出来,然后让产品去验证、迭代,等客户数大幅上涨到1000万后,再考虑升级为推拉集合模式。如果是按推荐排序,那么是另外的考虑了,架构会完全不一样,这个后面专门文章介绍。如果选择了Tablestore,那么同步库表设计结构如下: 主键列第一列主键第二列主键属性列属性列属性列列名user_idsequence_idsender_idmessage_idother解释消息接收者用户ID消息顺序ID,可以使用timestamp + send_user_id,也可以直接使用Tablestore的自增列。发送者的用户IDstore_table中的message_id列的值,也就是消息ID。通过sender_id和message_id可以到store_table中查询到消息内容其他内容,同步库中不需要包括消息内容。确定了同步库的架构如下: 4. 元数据前面介绍了同步和存储后,整个Feed流系统的基础功能完成了,但是对于一个完整Feed流产品而言,还缺元数据部分,接下来,我们看元数据如何处理: Feed流系统中的元数据主要包括: 用户详情和列表。关注或好友关系。推送session池。我们接下来逐一来看。 4.1 用户详情和列表 主要是用户的详情,包括用户的各种自定义属性和系统附加的属性,这部分的要求只需要根据用户ID查询到就可以了。 可以采用的分布式NoSQL系统或者关系型数据库都可以。 如果使用NoSQL数据库Tablestore,那么用户详情表设计结构如下: 主键顺序第一列主键属性列-1属性列-2......字段名user_idnick_namegenderother备注主键列,用于唯一确定一个用户用户昵称,用户自定义属性用户性别,用户自定义属性其他属性,包括用户自定义属性列和系统附加属性列。Tablestore是FreeSchema类型的,可以随时在任何一行增加新列而不影响原有数据。4.2 关注或好友关系 这部分是存储关系,查询的时候需要支持查询关注列表或者粉丝列表,或者直接好友列表,这里就需要根据多个属性列查询需要索引能力,这里,存储系统也可以采用两类,关系型、分布式NoSQL数据库。 如果已经有了关系型数据库了,且数据量较少,则选择关系型数据库,比如MySQL等。如果数据量比较大,这个时候就有两种选择: 需要分布式事务,可以采用支持分布式事务的系统,比如分布式关系型数据库。使用具有索引的系统,比如云上的Tablestore,更简单,吞吐更高,扩容能力也一并解决了。如果使用Tablestore,那么关注关系表设计结构如下: Table:user_relation_table 主键顺序第一列主键第一列主键属性列属性列Table字段名user_idfollow_user_idtimestampother备注用户ID粉丝用户ID关注时间其他属性列多元索引的索引结构: Table字段名user_idfollow_user_idtimestamp是否Index是是是是否enableSortAndAgg是是是是否store是是是查询的时候: 如果需要查询某个人的粉丝列表:使用TermQuery查询固定user_id,且按照timestamp排序。如果需要查询某个人的关注列表:使用TermQuery查询固定follow_user_id,且按照timestamp排序。当前数据写入Table后,需要5~10秒钟延迟后会在多元索引中查询到,未来会优化到2秒以内。除了使用多元索引外,还可以使用GlobalIndex。4.3 推送session池 ...

July 2, 2019 · 1 min · jiezi

大型网站系统与Java中间件读书笔记-中

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾上一篇: 《大型网站系统与Java中间件》读书笔记(一)这周周末读了第四章,现在过来做做笔记,希望能帮助到大家。 注:在看这篇文章之前,强烈建议先看看我之前写过的一篇SpringCloud入门文章:外行人都能看懂的SpringCloud,错过了血亏!。看完再回头看这篇文章,你会发现:这本书讲的设计与实现在SpringCloud中几乎都有对应的组件支持。 一、服务框架的设计从上一篇我们讲到,应用拆开了以后,不同功能/模块之间的调用不再单纯通过本机调用,引入了远程的服务调用。 而远程的服务调用这个东东会很难吗?说白了,不就是两台服务器之间通信吗? 这时候,你能想到什么?必定是Socket吧。没错,我们通过Socket肯定是可以完成两个系统之间的通信的问题的。(Socket相信大家在学习基础的时候已经写过Demo了,这我就不多BB了) 一两个系统的Socket写起来没啥,但我们应用拆分之后,系统可是会变得很多很多。 系统很多的情况下,我们在写远程调用代码的时候就可能要考虑到以下的问题: 我们肯定是不希望每次远程调用的时候都贴上重复的Socket代码,要是调用远程方法像调用本地方法一样简单就好了。某个服务应用为了实现高可用,集群了(多台机器部署同一套应用)。那我远程调用的时候选择哪一台机器进行调用?网络之间的传输协议用现成的HTTP呢?还是自定义一套通信协议呢?因为我们想调用远程方法像调用本地方法一样,那么在网络上就需要传输Java对象,要传输Java对象,就必须得对其进行序列化和反序列化的处理。能实现序列化的操作也有很多,选择哪一种方式呢?网络之间的通讯也有bio、nio、以及aio这几种模式,一般来说我们会选择哪种比较多?如果不了解nio的同学,可以阅读我以前写过的笔记(nio你了解多少?)….等等等由于系统之间的调用会非常多,我们自然是不希望写重复的代码的,所以服务框架(也可以说是RPC框架)就应运而生了【说白了就是专门处理远程服务调用的框架】。有了服务框架,我们就可以实现多个系统之间以统一的方式来进行远程调用了。 推荐阅读:RPC太太太太太太太容易理解啦!一个服务框架需要考虑的问题其实远不止上面所列出的那些,比如说: 服务框架与Web应用和Web容器的关系是什么?服务框架和应用是绑定在一起吗?(服务框架作为Web应用的一个依赖包),还是说服务框架只是Web应用的一个扩展(没有和Web应用打包绑定在一起)服务框架的jar包和Web应用的jar包冲突了怎么办?为了保证系统的稳定性,流量控制也应该要考虑到在远程调用的时候,需不需要以更细粒度的方式来进行选择(之前说的是选择哪台机器,但可以细粒度到机器下的接口或者方法)....等等二、服务框架的技术实现思路在书中给出了设计服务框架时需要考虑的问题的同时也给出了一些实现思路,我摘录一些我觉得比较有参考意义的说说。 2.1 像本地一样调用远程服务比如服务消费方在执行orderService.buy("HHKB键盘")时,实质上调用的是远端的服务。这用到啥技术?明显就是动态代理(给女朋友讲解什么是代理模式) 在实现的时候有三个基础属性可以参考一下: interfaceName— 确定调用的是哪一个接口version— 如果接口进行升级了,可以使用version来进行区分和隔离group— 对远程服务的机器进行分组,那么调用的时候就可以选择不同的分组来调用(调用者对统一服务的调用进行隔离)2.2 其他当远程调用服务的时候,不需要每次都要去注册中心查找可用的地址,而是把地址缓存在调用方。当服务有变化的时候,主动告诉调用者就行了。流量控制一般会基于两个维度去考虑:一、自身的接口和方法。二、请求的来源并不是所有的请求都要经过服务提供者。像走缓存这样频繁的操作(而且大多数都是会成功的),直接在调用方调用就ok了 最后总的来说,书的第四章主要是在讲解在设计服务框架的时候应该要考虑到哪些方面,可以以什么方案来解决,看得还是非常过瘾的(这只是我的个人笔记,书上还有很多的内容)。强烈建议配合我之前写过的一篇SpringCloud入门文章:外行人都能看懂的SpringCloud,错过了血亏!食用。 乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,关注即可获取! 觉得我的文章写得不错,点赞!

July 1, 2019 · 1 min · jiezi

支付宝的商业与技术创新双轮驱动-创造数字时代普惠金融奇迹

2019年6月28日,在中国国际软件博览会上,蚂蚁金服金融科技产品技术总监杨冰发表主题演讲,分享了蚂蚁金服在过去的十多年里,是如何通过商业创新与技术创新的双轮驱动,创造出数字时代的普惠金融“奇迹”。 十多年以前,大概很难有人能想象到如今我们习以为常的生活场景:只要带上手机就可以放心出门,从购物到餐饮,从打车到住宿,甚至理财和贷款,都只需轻点几下屏幕。 十多年以前,大概也很难有人能想象到金融业会发生如此深刻的变革:人满为患的实体网点、冗长的申请表单和繁复的审批流程都逐渐成为过去时;传统金融行业因成本和风控问题而难以触达的用户,比如小微企业和个人,也日渐成为银行的目标用户群体。 越便捷的服务,需要越强大的技术蚂蚁金服为金融业的变革做了些什么? 在过去的十五年中,它通过技术重塑了支付服务小微贷款服务,让普惠金融服务对于每一个普通的中国人来说,都变得触手可及。 基于互联网和移动互联网,蚂蚁金服的产品为用户带来了前所未有的轻松和便捷:转账无需再去银行排队,在只需在手机上轻点几下;消费无需现金,二维码支付已经遍布中国的大街小巷;即使没有信用卡,只要开通花呗即可先付后还;余额宝可以让用户通过手机就能实现理财,而如果一名小微企业主想要贷款,只需要花3分钟在网上填写申报材料,1秒钟就能实现贷款到账,整个过程中零人工干预。 但是,用户对于快捷和便利的要求不断增长,也给金融机构带来的全新的挑战。在挑战面前,唯有技术的创新和发展才是最有力的武器。 通过智能手机,用户可以随时随地发起交易,线上交易流量远非传统银行柜台业务可比。在类似“双十一”的大促活动中,每秒的交易峰值可达数十万笔,在这样巨大的流量面前,如何保持交易系统的稳定、安全、高可用,保证数据没有任何丢失和偏差,这是互联网时代的“新型银行”必须面对的难题。 金融交易技术中,最关键的是分布式数据库能力。随着蚂蚁金服的业务量突飞猛进,依靠开源的分布式系统已经不足以解决问题。2009 年,蚂蚁金服自主研发金融级分布式关系数据库 OceanBase,这是一个专长于高可用、一致性的分布式数据库,结合蚂蚁自研的金融级分布式中间件,整个系统具备百万级每秒的伸缩支付能力,成功经受住了“双十一”交易量每年翻三倍的考验。 金融交易的另一个关键点是风控,这关系到金融业务的生命线。传统金融机构用严格的审核来控制风险,但在互联网时代,为了用户体验及时流畅,消费、信贷、保险等交易的审核都必须在尽可能短的时间内完成。 对于金融机构而言,这可谓压力山大:交易是否违规?是否虚假交易?是否合谋套现?如何在不借助担保材料的情况下来判断借款者是否可靠?如何甄别诈骗和洗钱?如何避免坏账和资金损失?这一系列复杂的问题,都要在毫秒级的时间中里找到正确答案。 传统金融机构依靠人力来审核的做法显然是行不通的,不但成本高企,时间也不允许,因此必须要有一套数据和算法构筑的庞大、复杂而精密的平台,依靠海量的计算来做出精准的决策。 这不是一件简单的事,因为每一笔交易都关系到真金白银,出错就会带来资损,金融级对于精确和稳定的要求非常高,尤其在延时性要求也非常苛刻的情况下,对技术是很大的考验。举例而言,如果要甄别一个花呗账号是否有套现嫌疑,既要做实时的特征计算,还要用图计算去查看与这个账号关联的资金情况。如果在多种计算模式之间来回切换,不仅会增加成本,还会带来延时,影响用户体验。 蚂蚁金服:不是取代者,而是支持者强大的技术支持,让蚂蚁金服实现了快、稳、准,许多本来难以享受金融服务的企业和个人,如今也可以享受到普惠金融带来的便利。在传统金融机构看来,像这样的新型科技金融机构是强有力的竞争者,发达国家的许多银行家担心,新兴科技公司的崛起将挤压他们的份额。 但在蚂蚁金服看来,这种担心是多余的:蚂蚁金服不会取代传统机构,而是扮演支持者的角色,通过技术开放帮助机构提升服务效率和质量。 自研技术的基础上,蚂蚁金服还一直在扮演着推动技术开放,为传统金融业赋能的角色。因为蚂蚁金服定义中的普惠金融,不仅是自身要服务大量的用户,让原本难以享受到便捷金融服务的用户受益;还要通过技术的开放,让更多的金融机构具备更好地服务大量用户的能力。 在金融业变革的大势之中,许多传统金融机构都走上了数字化转型的道路。转型之中,他们不约而同地遇到了相似的门槛:如何快速搭建线上业务?如何利用互联网获客、扩大业务规模和覆盖范围?如何基于互联网用户群体的特性开发新的产品? 蚂蚁将自己沉淀下来的技术和经验开放出来,让传统金融机构在面对这类问题时,手握更具效率的工具,也少走了很多弯路。 三大PaaS产品都是蚂蚁金服技术开放的结晶:mPaaS(mobile PaaS)能够快速帮助这些机构开发移动APP;bPaaS(business PaaS)是凝结了蚂蚁金服多年来积累的分布式金融核心能力的套件,能帮助这些机构在最短三个月内快速“复制支付宝的能力”;dPaaS作为一个数据智能平台,借助强大的底层数据引擎,通过海量的计算,能帮助这些机构获得基于大数据的业务分析洞察能力和实时智能决策能力。 mPaaS自2017年下半年开始推广以来,已经帮助多家股份制银行和城市商业银行完成互联网金融升级,如广发银行,华夏银行,苏州银行等。mPaaS团队仅用了不到三个月的时间,就帮助铁路售票系统12306 App完成重构,极大提升了性能和效率。此外,mPaaS还和上海地铁深入合作,推出了“Metro大都会 App”,实现扫码进站,为日均客流量超过1100万人次的上海地铁解决了排队买票的问题。 bPaaS的面世,为传统金融机构的转型提供的现成的平台,让他们不必再从零开始摸索和开发自己的分布式业务系统,节约大量时间的同时,也极大减少了分布式技术在核心业务中的落地难度。bPaaS中整合的是蚂蚁金服十几年来在金融业务实践中经过无数次验证的技术和解决方案,在保持银行传统核心稳定的前提下,bPaaS可以根据不同银行差异化的业务场景,快速定制新业务场景。随着bPaaS的开放,金融机构在最短三个月内“复制蚂蚁金服的核心技术能力”,完全可能成为现实。 dPaaS则针对传统金融机构转型中使用数据门槛过高的痛点,主要提供“三合一”的数据智能能力:处理海量数据的工具,收集和存储数据的标准,使用数据的方法论。在风控和营销场景之中,dPaaS都有突出的表现,在dPaaS的帮助之下,传统金融机构能够更为顺畅地使用数据来提升业务,将手中的数据资产切实有效地转化为业务能力,实现数据的价值。 《经济学人》特别指出,技术对金融业的意义深远。科技创新可以孕育更灵活、便利、开放的金融系统,而智能手机和数字技术在金融业的广泛应用将成为推动社会经济发展和普惠的最佳途径之一。在运用数据和数据技术规避风险、降低成本、促进业务成长、推动普惠金融等方面,以蚂蚁金服为代表的中国金融科技公司已经走出了一条自己的道路,同时,也在不断将技术进步的趋势推广到全世界。 本文作者:华蒙阅读原文 本文为云栖社区原创内容,未经允许不得转载。

July 1, 2019 · 1 min · jiezi

分布式系统设计模式

layout: posttitle: 分布式系统设计模式category: 技术keywords: 架构,分布式,微服务,后端,分布式系统,设计模式 comments: true概述这篇文章是对于【分布式系统设计模式】的个人理解和部分翻译。 文章探讨了关于《基于容器化软件组件的微服务架构》。 其实容器化编程的发展路径和面向对象编程有异曲同工之妙--都是将复杂的系统进行抽象、解耦,然后通过一定的方式组合起来。 既然我们要组合,肯定会有面对不同情况的不同组合方式。所以,这些不同的组合方式也会有几个常用的固定模式。而这个正式我们要探讨的--分布式系统设计模式。 说到分布式,第一个联想到的应该就的容器化。为什么?其实容器化和分布式本没有交集,只是因为我们发现容器化是一个实现分布式的高效的方法。 容器化设置了一个天然的边界,边界之外用接口进行通信。有了这个边界的好处就是,任何意料之外的情况都可以被限制在最小的影响范围,毕竟我们构建的是一个大型的复杂系统。 我认为,用FMEA模型能很好的描述为什么会采用容器化去解构分布式系统。(FMEA,可以理解为:失控的状态一定会发生,我们要做的是控制失控的范围) 所以,我们接下来要说的设计模式基本上都是和容器相关,我们需要把容器作为一等公民去看。毕竟这是写 Kubernetes 的哥们写的。 单容器管理者模式 (Single-container management patterns)我们为容器增加一些可控接口,比如 run(), stop(), pause(),使得容器对外来说是可控的。 也正是因为广泛的 http 协议支持,你完全可以通过 http 和 JSON这样的序列化方式去构造你应用的对外的 API。 一般来说我们的设计方针都是一个容器提供一种服务。同时容器会为其上下游提供接口。 什么接口? 向上,提供容器本身丰富的信息接口。能够为特定的监控容器运行状态的应用提供信息。 向下,提供了控制容器本身的接口。使得分布式系统能够更有效的管理整个应用的生命周期,以及应用的优先级。 比如,一个集群的管理系统,能够设置集群处理任务的优先级。(比如 K8s 中的抢占式调度) 所以一旦采用这种模式的话,你会需要一个统一的管理平台,通过接口去管理(组管理)单个容器。 单节点-多容器应用模式 (Single-node, multi-container application patterns)这种模式比较好理解,有些容器应用是需要“共生”的,所以我们会将其放在同一个节点上。一旦这样,分布式系统会对容器组做联合调度。比如 K8s 里将调度单位描述成了 Pods(一个 Pod 可能包含多个容器),Nomad 则称其为 task groups。下面几个就是常用的单节点多容器的设计模式: 副载模式(Sidecar pattern)多容器部署最通用的一种模式,就是 sidecar 模式。其实大家都直接称呼 Sidecar 模式,不会翻译成副载。 那 Sidecar 是个啥样子呢? 举个例子吧:我们有一个主容器是 Web Server,我们需要收集 Web Server 所产生的日志。所以我们会有一个专门的 sidecar 容器,负责收集日志并把日志存储到集群的存储系统。 ...

June 27, 2019 · 1 min · jiezi

TiDB-在知乎万亿量级业务数据下的实践和挑战

作者:孙晓光,知乎搜索后端负责人,目前承担知乎搜索后端架构设计以及工程团队的管理工作。曾多年从事私有云相关产品开发工作关注云原生技术,TiKV 项目 Committer。 本文根据孙晓光老师在 TiDB TechDay 2019 北京站上的演讲整理。 本次分享首先将从宏观的角度介绍知乎已读服务的业务场景中的挑战、架构设计思路,然后将从微观的角度介绍其中的关键组件的实现,最后分享在整个过程中 TiDB 帮助我们解决了什么样的问题,以及 TiDB 是如何帮助我们将庞大的系统全面云化,并推进到一个非常理想的状态的。 一、业务场景知乎从问答起步,在过去的 8 年中逐步成长为一个大规模的综合性知识内容平台,目前,知乎上有多达 3000 万个问题,共收获了超过 1.3 亿个回答,同时知乎还沉淀了数量众多的文章、电子书以及其他付费内容,目前注册用户数是 2.2 亿,这几个数字还是蛮惊人的。我们有 1.3 亿个回答,还有更多的专栏文章,所以如何高效的把用户最感兴趣的优质内容分发他们,就是非常重要的问题。 <center>图 1</center> 知乎首页是解决流量分发的一个关键的入口,而已读服务想要帮助知乎首页解决的问题是,如何在首页中给用户推荐感兴趣的内容,同时避免给用户推荐曾经看过的内容。已读服务会将所有知乎站上用户深入阅读或快速掠过的内容记录下来长期保存,并将这些数据应用于首页推荐信息流和个性化推送的已读过滤。图 2 是一个典型的流程: <center>图 2</center> 当用户打开知乎进入推荐页的时候,系统向首页服务发起请求拉取“用户感兴趣的新内容”,首页根据用户画像,去多个召回队列召回新的候选内容,这些召回的新内容中可能有部分是用户曾经看到过的,所以在分发给用户之前,首页会先把这些内容发给已读服务过滤,然后做进一步加工并最终返回给客户端,其实这个业务流程是非常简单的。 <center>图 3</center> 这个业务第一个的特点是可用性要求非常高,因为首页可能是知乎最重要的流量分发渠道。第二个特点是写入量非常大,峰值每秒写入 40k+ 条记录,每日新增记录近 30 亿条。并且我们保存数据的时间比较长,按照现在产品设计需要保存三年。整个产品迭代到现在,已经保存了约一万三千亿条记录,按照每月近一千亿条的记录增长速度,大概两年之后,可能要膨胀到三万亿的数据规模。 <center>图 4</center> 这个业务的查询端要求也很高。首先,产品吞吐高。用户在线上每次刷新首页,至少要查一次,并且因为有多个召回源和并发的存在,查询吞吐量还可能放大。峰值时间首页每秒大概产生 3 万次独立的已读查询,每次查询平均要查 400 个文档,长尾部分大概 1000 个文档,也就是说,整个系统峰值平均每秒大概处理 1200 万份文档的已读查询。在这样一个吞吐量级下,要求的响应时间还比较严格,要求整个查询响应时间(端到端超时)是 90ms,也就意味着最慢的长尾查询都不能超过 90ms。还有一个特点是,它可以容忍 false positive,意味着有些内容被我们过滤掉了,但是系统仍然能为用户召回足够多的他们可能感兴趣的内容,只要 false positive rate 被控制在可接受的范围就可以了。 二、架构设计由于知乎首页的重要性,我们在设计这个系统的时候,考虑了三个设计目标:高可用、高性能、易扩展。首先,如果用户打开知乎首页刷到大量已经看过的内容,这肯定不可接受,所以对已读服务的第一个要求是「高可用」。第二个要求是「性能高」,因为业务吞吐高,并且对响应时间要求也非常高。第三点是这个系统在不断演进和发展,业务也在不断的更新迭代,所以系统的「扩展性」非常重要,不能说今天能支撑,明天就支撑不下来了,这是没法接受的。 接下来从这三个方面来介绍我们具体是如何设计系统架构的。 2.1 高可用 ...

June 27, 2019 · 3 min · jiezi

Redis管道

Redis之管道的使用原文地址: https://blog.piaoruiqing.com/blog/2019/06/24/redis管道 关键词Redis Pipelining: 客户端可以向服务器发送多个请求而无需等待回复, 最后只需一步即可读取回复. RTT(Round Trip Time): 往返时间. 为什么要用管道Redis是使用client-server模型和Request/Response协议的TCP服务器. 这意味着通常通过以下步骤完成请求: 客户端向服务器发送查询, 并通常以阻塞方式从套接字读取服务器响应.服务器处理该命令并将响应发送回客户端.应用程序与Redis通过网络进行连接, 可能非常快(本地回环), 也可能很慢. 但无论网络延迟是多少, 数据包都需要时间从客户端传输到服务器, 然后从服务器返回到客户端以进行回复(此时间称为RTT). 当客户端需要连续执行许多请求时(例如, 将多个元素添加到同一列表或使用多个键填充数据库), 很容易发现这种频繁操作很影响性能. 使用管道将多次操作通过一次IO发送给Redis服务器, 然后一次性获取每一条指令的结果, 以减少网络上的开销. 频繁操作但未使用管道的情形如下图: 使用管道后如下图: 如何使用Jedis/** jedis pool */private final Logger LOGGER = LoggerFactory.getLogger(getClass());private static final JedisPool POOL = new JedisPool(new JedisPoolConfig(), "test-redis-server", 6379);/** * test pipelining with Jedis */@Testpublic void testPipelining() { try (Jedis jedis = POOL.getResource()) { Pipeline pipelined = jedis.pipelined(); // (一) Response<String> response1 = pipelined.set("mykey1", "myvalue1"); Response<String> response2 = pipelined.set("mykey2", "myvalue2"); Response<String> response3 = pipelined.set("mykey3", "myvalue3"); pipelined.sync(); // (二) LOGGER.info("cmd: SET mykey1 myvalue1, result: {}", response1.get()); // (三) LOGGER.info("cmd: SET mykey2 myvalue2, result: {}", response2.get()); LOGGER.info("cmd: SET mykey3 myvalue3, result: {}", response3.get()); }}(一): jedis.pipelined(): 获取一个Pipeline用以批量执行指令.(二): pipelined.sync(): 同步执行, 通过读取全部Response来同步管道, 这个操作会关闭管道.(三): response1.get(): 获取执行结果. 注意: 在执行pipelined.sync()之前, get是无法获取到结果的.Lettuce private final Logger LOGGER = LoggerFactory.getLogger(getClass());/** redis client */private static final RedisClient CLIENT = RedisClient.create("redis://@test-redis-server:6379/0");/** * test pipelining with Lettuce */@Testpublic void testPipelining() throws ExecutionException, InterruptedException { try (StatefulRedisConnection<String, String> connection = CLIENT.connect()) { RedisAsyncCommands<String, String> async = connection.async(); async.setAutoFlushCommands(false); RedisFuture<String> future1 = async.set("mykey1", "myvalue1"); RedisFuture<String> future2 = async.set("mykey2", "myvalue2"); RedisFuture<String> future3 = async.set("mykey3", "myvalue3"); async.flushCommands(); LOGGER.info("cmd: SET mykey1 myvalue1, result: {}", future1.get()); LOGGER.info("cmd: SET mykey2 myvalue2, result: {}", future1.get()); LOGGER.info("cmd: SET mykey3 myvalue3, result: {}", future1.get()); }}RedisTemplateprivate final Logger LOGGER = LoggerFactory.getLogger(getClass());@Resourceprivate StringRedisTemplate stringRedisTemplate;/** * test pipelining with RedisTemplate */@Testpublic void testPipelining() { List<Object> objects = stringRedisTemplate.executePipelined((RedisCallback<Object>)connection -> { connection.set("mykey1".getBytes(), "myvalue1".getBytes()); connection.set("mykey2".getBytes(), "myvalue2".getBytes()); connection.set("mykey3".getBytes(), "myvalue3".getBytes()); return null; // (一) }); LOGGER.info("cmd: SET mykey myvalue, result: {}", objects);}(一): 此处必须返回null简单对比测试redis服务器运行在同一个路由器下的树莓派上./** * pipeline vs direct */@Testpublic void compared() { try (Jedis jedis = POOL.getResource()) { // warm up jedis.set("mykey", "myvalue"); } try (Jedis jedis = POOL.getResource()) { long start = System.nanoTime(); Pipeline pipelined = jedis.pipelined(); for (int index = 0; index < 500; index++) { pipelined.set("mykey" + index, "myvalue" + index); } pipelined.sync(); long end = System.nanoTime(); LOGGER.info("pipeline cost: {} ns", end - start); } try (Jedis jedis = POOL.getResource()) { long start = System.nanoTime(); for (int index = 0; index < 500; index++) { jedis.set("mykey" + index, "myvalue" + index); } long end = System.nanoTime(); LOGGER.info("direct cost: {} ns", end - start); }}使用Jedis执行500条set, 执行结果如下: ...

June 25, 2019 · 2 min · jiezi

MongoDB-42-新特性解读

云数据库 MongoDB 版 基于飞天分布式系统和高性能存储,提供三节点副本集的高可用架构,容灾切换,故障迁移完全透明化。并提供专业的数据库在线扩容、备份回滚、性能优化等解决方案。 了解更多 MongoDB World 2019 上发布新版本 MongoDB 4.2 Beta,包含多项数据库新特性,本文尝试从技术角度解读。 Full Text SearchMongoDB 4.2 之前,全文搜索(Full Text Search)的能力是靠 Text Index 来支持的,在 MongoDB-4.2 里,MongoDB 直接与 Lucene 等引擎整合,在 Atlas 服务里提供全文建索的能力。 MongoDB FTS 原理用户可以在 Atlas 上,对集合开启全文索引,后台会开起 Lucene 索引引擎(索引引擎、查询引擎均可配置),对存量数据建立索引。对于开启全文建索的集合,新写入到 MongoDB 的数据, 后台的服务会通过 Change Stream 的方式订阅,并更新到 Lucene 索引引擎里。索引的查询直接以 MongoDB Query 的方式提供,Mongod 收到请求会把请求转发到 Lucene 引擎,收到建索结果后回复给客户端。Full Text Search 示例下面是一个 Full Text Search 使用的简单示例,整个使用体验非常简单,除了需要在 Atlas 控制台上建索引,其他跟正常使用 MongoDB 毫无差别,随着这块能力的完善,能覆盖很多 Elastic Search 的场景。 Step1: 准备数据 ...

June 24, 2019 · 3 min · jiezi

Design-Review-架构规范

Design Review 是 TTM 过程中至关重要的一环,优秀的 Design review 不但能让技术方案的考虑更加周全,更多意义是避免潜在的线上 Bug 以及不必要的反复。 下面是我经常思考的一些问题,虽然不是每个项目都会涉及到这些点,而且也不应该被这些问题所局限,但作为一个参考,依然希望能给团队提供一个好的思考框架。 可用性外部依赖有哪些?如果这些外部依赖崩溃了我们有什么处理措施?我们 SLA 是什么?主要是指可用性目标几个 9? 50/90/99 分位数的响应时间是多少?QPS 是多少?我们的超时、重试、过载保护、服务降级机制是什么?如何避免雪崩我们的调用方有哪些?分别有什么服务配额?是否需要对关键的服务调用方单独部署?运维我们都有配置了哪些监控?如果出现问题,我们需要查看哪些信息?这些信息是否都有记录?报警的处理流程是什么?系统上线流程和步骤是什么,出了问题后是否可以回滚,以及怎么回滚?安全XSS,CSRF,SQL 注入这些是否需要处理?3 防怎么搞:防抓,防 DDOS,防恶意访问是否有请安全团队 review是否有风控的需求?信息存储时是否设计到密码、信用卡、身份证等敏感信息,这些信息是怎么存储和访问的?扩展性分层,分模块怎么拆分比较合理?拆分出来的模块可以搞成服务单独部署吗?应用层可以水平扩展吗?有用 session 吗?可以去掉 session 吗?如果系统的负载提升到以前的 3 到 10 倍,当前系统是否依然可用存储层面如果需要扩展存储怎么做?系统中有哪些上下依赖的节点 / 系统 / 服务?这些依赖是否会导致无法并行开发?能否去掉这些依赖?是否有数据访问 API? 数据 API 的设计对性能的考虑是什么?数据 API 对异常数据 (超大数据集、空数据集、错误数据、schema 异常...) 的处理是什么?存储数据计划怎么存储?会有可能的性能瓶颈吗?需要考虑一些缓存方案吗?有什么复杂 SQL 可能会导致慢查询吗?数据库的操作什么地方用了事务?什么情况会导致锁竞争?我们的锁策略是什么?一致性和可用性如何平衡?未来如果分库分表会有什么影响?缓存失效会有什么影响?缓存大量失效会有什么影响?冷启动有问题吗?有热点数据吗?多个缓存节点需要权衡可用性和一致性吗?存储时,是否需要分库,分表,选择的理由是什么?技术选型开发语言是什么,框架是什么为什么用他们?缓存用什么(tair/medis/redis/memached),web server 用什么?(nginx+php fpm/ apach php 扩展/jetty/tomcat/jboss),消息队列用什么 (rebbitmq/beanstalk/kafka/mafka/metaq/notify)?为什么用它们?DB 是否可以用、以及用哪种 no sql (hbase/tair/mangodb/redis) 来优化?业界或者其他团队是否有处理过类似问题?他们是怎么处理的?是否可以 copy 或者借鉴?服务调用和服务治理请求同步处理还是异步队列处理比较好?服务接口的 URI 设计合理吗?可以向下兼容吗?服务间的调用协议是什么(dubbo/hsf/thrift) ?有公司标准的调用协议可以用吗(hession/protobuffer)?客户端和服务端的调用协议是什么(http/ws/私有)?有公司标准的调用协议可以用吗?有什么服务治理相关的要考虑的吗?能否接入 SLA 服务治理?业务监控正常的业务逻辑外,可能会有哪些奇葩或者恶意的操作?我们应该怎么处理?除了系统上的监控外,需要什么业务维度的监控吗?log 是怎么记的?如果要 debug 能有什么开关迅速打开吗?log 怎么 rotate?log 会影响性能吗?复用项目中有用什么新技术吗?为什么要用新技术?未来其他人接手容易吗?项目中有什么复杂计算的地方吗?这些计算可以用什么算法优化吗?这个项目可以抽象出来什么可以复用的东西吗?项目中的什么可以不用自己做,调用现成服务吗?测试新的系统设计是否容易独立测试兼容性新的系统是否和已有系统冲突,怎么融进去

June 24, 2019 · 1 min · jiezi

Apache-Flink-结合-Kafka-构建端到端的-ExactlyOnce-处理

文章目录:Apache Flink 应用程序中的 Exactly-Once 语义Flink 应用程序端到端的 Exactly-Once 语义示例 Flink 应用程序启动预提交阶段在 Flink 中实现两阶段提交 Operator总结Apache Flink 自2017年12月发布的1.4.0版本开始,为流计算引入了一个重要的里程碑特性:TwoPhaseCommitSinkFunction(相关的Jira)。它提取了两阶段提交协议的通用逻辑,使得通过Flink来构建端到端的Exactly-Once程序成为可能。同时支持一些数据源(source)和输出端(sink),包括Apache Kafka 0.11及更高版本。它提供了一个抽象层,用户只需要实现少数方法就能实现端到端的Exactly-Once语义。 有关TwoPhaseCommitSinkFunction的使用详见文档: TwoPhaseCommitSinkFunction。或者可以直接阅读Kafka 0.11 sink的文档: kafka。 接下来会详细分析这个新功能以及Flink的实现逻辑,分为如下几点。 描述Flink checkpoint机制是如何保证Flink程序结果的Exactly-Once的显示Flink如何通过两阶段提交协议与数据源和数据输出端交互,以提供端到端的Exactly-Once保证通过一个简单的示例,了解如何使用TwoPhaseCommitSinkFunction实现Exactly-Once的文件输出一、Apache Flink应用程序中的Exactly-Once语义当我们说『Exactly-Once』时,指的是每个输入的事件只影响最终结果一次。即使机器或软件出现故障,既没有重复数据,也不会丢数据。 Flink很久之前就提供了Exactly-Once语义。在过去几年中,我们对Flink的checkpoint机制有过深入的描述,这是Flink有能力提供Exactly-Once语义的核心。Flink文档还提供了该功能的全面概述。 在继续之前,先看下对checkpoint机制的简要介绍,这对理解后面的主题至关重要。 次checkpoint是以下内容的一致性快照:应用程序的当前状态输入流的位置Flink可以配置一个固定的时间点,定期产生checkpoint,将checkpoint的数据写入持久存储系统,例如S3或HDFS。将checkpoint数据写入持久存储是异步发生的,这意味着Flink应用程序在checkpoint过程中可以继续处理数据。 如果发生机器或软件故障,重新启动后,Flink应用程序将从最新的checkpoint点恢复处理; Flink会恢复应用程序状态,将输入流回滚到上次checkpoint保存的位置,然后重新开始运行。这意味着Flink可以像从未发生过故障一样计算结果。 在Flink 1.4.0之前,Exactly-Once语义仅限于Flink应用程序内部,并没有扩展到Flink数据处理完后发送的大多数外部系统。Flink应用程序与各种数据输出端进行交互,开发人员需要有能力自己维护组件的上下文来保证Exactly-Once语义。 为了提供端到端的Exactly-Once语义 – 也就是说,除了Flink应用程序内部,Flink写入的外部系统也需要能满足Exactly-Once语义 – 这些外部系统必须提供提交或回滚的方法,然后通过Flink的checkpoint机制来协调。 分布式系统中,协调提交和回滚的常用方法是两阶段提交协议。在下一节中,我们将讨论Flink的TwoPhaseCommitSinkFunction是如何利用两阶段提交协议来提供端到端的Exactly-Once语义。 二、Flink应用程序端到端的Exactly-Once语义我们将介绍两阶段提交协议,以及它如何在一个读写Kafka的Flink程序中实现端到端的Exactly-Once语义。Kafka是一个流行的消息中间件,经常与Flink一起使用。Kafka在最近的0.11版本中添加了对事务的支持。这意味着现在通过Flink读写Kafaka,并提供端到端的Exactly-Once语义有了必要的支持。 Flink对端到端的Exactly-Once语义的支持不仅局限于Kafka,您可以将它与任何一个提供了必要的协调机制的源/输出端一起使用。例如Pravega,来自DELL/EMC的开源流媒体存储系统,通过Flink的TwoPhaseCommitSinkFunction也能支持端到端的Exactly-Once语义。 在今天讨论的这个示例程序中,我们有: 从Kafka读取的数据源(Flink内置的KafkaConsumer)窗口聚合将数据写回Kafka的数据输出端(Flink内置的KafkaProducer)要使数据输出端提供Exactly-Once保证,它必须将所有数据通过一个事务提交给Kafka。提交捆绑了两个checkpoint之间的所有要写入的数据。这可确保在发生故障时能回滚写入的数据。但是在分布式系统中,通常会有多个并发运行的写入任务的,简单的提交或回滚是不够的,因为所有组件必须在提交或回滚时“一致”才能确保一致的结果。Flink使用两阶段提交协议及预提交阶段来解决这个问题。 在checkpoint开始的时候,即两阶段提交协议的“预提交”阶段。当checkpoint开始时,Flink的JobManager会将checkpoint barrier(将数据流中的记录分为进入当前checkpoint与进入下一个checkpoint)注入数据流。 brarrier在operator之间传递。对于每一个operator,它触发operator的状态快照写入到state backend。 数据源保存了消费Kafka的偏移量(offset),之后将checkpoint barrier传递给下一个operator。 这种方式仅适用于operator具有『内部』状态。所谓内部状态,是指Flink state backend保存和管理的 -例如,第二个operator中window聚合算出来的sum值。当一个进程有它的内部状态的时候,除了在checkpoint之前需要将数据变更写入到state backend,不需要在预提交阶段执行任何其他操作。Flink负责在checkpoint成功的情况下正确提交这些写入,或者在出现故障时中止这些写入。 三、示例Flink应用程序启动预提交阶段但是,当进程具有『外部』状态时,需要作些额外的处理。外部状态通常以写入外部系统(如Kafka)的形式出现。在这种情况下,为了提供Exactly-Once保证,外部系统必须支持事务,这样才能和两阶段提交协议集成。 在本文示例中的数据需要写入Kafka,因此数据输出端(Data Sink)有外部状态。在这种情况下,在预提交阶段,除了将其状态写入state backend之外,数据输出端还必须预先提交其外部事务。 当checkpoint barrier在所有operator都传递了一遍,并且触发的checkpoint回调成功完成时,预提交阶段就结束了。所有触发的状态快照都被视为该checkpoint的一部分。checkpoint是整个应用程序状态的快照,包括预先提交的外部状态。如果发生故障,我们可以回滚到上次成功完成快照的时间点。 下一步是通知所有operator,checkpoint已经成功了。这是两阶段提交协议的提交阶段,JobManager为应用程序中的每个operator发出checkpoint已完成的回调。 数据源和 widnow operator没有外部状态,因此在提交阶段,这些operator不必执行任何操作。但是,数据输出端(Data Sink)拥有外部状态,此时应该提交外部事务。 ...

June 21, 2019 · 1 min · jiezi

分布式数据库选型数据水平拆分方案

概述水平拆分的概念随着分布式数据库的推广已为大部分人熟知。分库分表、异构索引、小表广播、这些功能几乎是产品功能需求标配。然而有些客户使用分布式数据库后的体验不尽如意。本文尝试从数据的角度总结分布式数据的复制(replication)和分区(partition)技术原理和方案,其中分区也有称为分片(sharding),希望能引起读者一些思考,在分布式数据库选型中能注意这些细节的区别,选择适合业务的数据水平拆分方案。 分布式数据库架构分布式数据库以集群形式存在,有多个节点。集群架构有共享磁盘架构(shared-disk)和无共享架构(shared-nothing)。后者有时也称为水平扩展(horizontal scale)或向外扩展(scale out),本文主要总结无共享架构方案。 无共享架构的各个节点之间的通信都是软件层面使用网络实现,不同产品在架构不同导致这个细节也不同。有些架构是计算与存储分离。计算节点特点是无状态(即数据不要求持久化),通过集群方式管理,可以水平扩展;存储节点有数据,使用复制和分区技术,节点间任务集中调度或者独立交互。了解这个架构细节都可用性分析会更加具体。具体分布式数据库架构有哪些请参考《一些关系数据库的架构总结》。 这里节点的实际体现形式可以是一个机器,也可以是机器上的一个实例。比如说有些数据库支持单机安装多个实例,如MySQL。每个节点具备一定的资源和能力。资源指的是CPU、内存和磁盘,能力是提供数据读写和存储能力。分布式数据库需要把多个节点的能力聚集到一起集中管理,只是不同分布式数据库产品对资源的管理能力各有特点。 在分布式数据库里,数据随处可见,这是最容易让人混淆的地方。因为数据经过复制和分区后会有两种存在形式:副本(replica)和分区(partition)。 数据的复制(replication)复制(replication)指在几个不同的节点上保存数据的相同副本(replica)。复制提供了冗余的能力。其作用一是提供高可用能力:如果一个节点不可用,剩余的节点可以快速提供数据服务。作用二是提供读写分离能力。常见的有两副本和三副本架构。 多个副本内容相同,角色会有区分。常见的是一个副本是Leader角色(有的也称主副本),默认提供读写服务;其他副本是Follower角色(有的也称备副本),默认不提供服务。这种架构也称为基于单Leader的(Single Leader-based)。还有其他架构是多Leader的,每个Leader都有数据要复制到其他Leader或Follower,这种架构会有个明显的问题就是数据冲突处理。如果产品层面不处理,用户直接使用风险会很高。 后面讨论的是前者:基于单Leader副本架构。 多副本之间数据同步不是依赖业务多写,而是采用副本间复制事务日志(Redo)技术。复制的方式有同步复制和异步复制。使用同步复制方式,备副本要收到Redo并落盘主副本才能提交,也叫强同步;使用异步复制方式,Follower副本相对Leader副本内容会有延时,具体延时多少取决于Leader副本上事务量、网络传输速度、Follower副本所在节点的负载和能力。强同步的缺点时主副本写性能会下降,同时如果备副本不可用主副本也不能提供服务(变相的解决方案是复制方式降级为异步复制)。 传统关系型数据库还有一种用法一主两备架构,使用同步复制,只要任何一个备副本收到Redo,主副本的事务就可以提交。这个方案优点是保障了数据在多个副本中存在,高可用时有候选副本,也不用担心挂掉一个备副本会影响主副本。它的缺点是不能自动知道哪个候选副本拥有主副本最新最全的数据,也不强制要求两个备副本都要拥有全部数据。 还有一类三副本架构在复制时使用的是Paxos协议,三副本会就Redo落盘事件进行投票,有两个副本成功了Leader副本的事务即可提交。这个表面上跟上面传统一主两备的三副本效果一样,实际上还是有区别的。区别一是使用Paxos协议时,如果Leader副本自身投票慢了,两个Follower副本投票成功,Leader副本的事务也是能提交的;区别二是第三个副本最终也必须写Redo成功,否则其状态就是异常,产品自身可以发现并自动修复(如重新创建一个副本);区别三是使用Paxos协议时,在Leader副本不可用时还可以自动选出新的Leader副本并且拥有老Leader副本的最新数据。这里其实说的是高可用机制。同样,这里对用户而言也不知道哪个Follower副本拥有最新最全的数据,如果访问Follower副本(读写分离),也可能发现数据有延时。 大部分数据库做副本复制使用的是Redo,也称为物理同步。在应用Redo的时候直接是数据块变更。使用物理同步机制的备副本是不提供写服务,不能修改。还有一类复制使用的是Binlog,也称为逻辑同步。Binlog里只包含已提交的事务,并且在应用的时候是通过执行SQL。使用逻辑同步的备副本通常也可能是主副本,可以修改(如MySQL的双向复制架构Master-Master)。如果目标端数据不对,应用SQL会失败,这个复制就会中断需要人介入处理。这也进一步加深了主备副本不一致的概率。 关于副本角色的粒度,有多种实现方案。 传统关系数据库主备架构,主副本或备副本的粒度就是实例。对于主实例(Primary)而言,里面所有数据库(或SCHEMA)的所有表的角色都是主;备实例(Standby)里数据则都是备副本。如果发生高可用切换,业务会中断几十秒或几分钟然后恢复(需要人工处理或自动化脚本处理)。 还有一种粒度是到表。即一个节点内有些表是Leader副本,有些表是Follower副本,这样这个节点就不能简单的说是主节点(实例)或备节点(实例)。这个副本角色细节业务也是可以获取的,如果发生高可用切换,业务会中断十几秒然后恢复。 还有一种粒度是存储级别的定长块。即一个节点的存储里,部分数据块是Leader副本,部分数据块是Follower副本。这种对业务就完全透明,业务基本不感知高可用切换。 数据的分区(partition)上面总结的是数据的复制(冗余,多副本),对于非常大的数据集(表)或者非常高的访问量(QPS),仅仅靠复制是不够的,还需要对数据进行分区(partition),也称为分片(sharding)。 分区粒度首先这里的分区(partition)是一种抽象概念,在不同数据库产品里这个体现是不一样的。如在MongoDB, Elasticsearch中体现为分片(shard),在HBase中体现为区域块(Region),Bigtable中体现为表块(tablet),ORACLE中体现为分区(partition),Couchbase中体现为虚拟桶(vBucket)。可见不同的数据库产品数据分区的粒度不同。在分布式关系数据库中间件中,分片的粒度是分表(物理表);在真正的分布式关系数据库里,分片的粒度有分区(partition,同ORACLE)或者区域块(Region)。 分区粒度对业务研发的使用体验影响很大。 比如说中间件常用分库分表方案,使用时对开发和运维会有一些要求。如建很多同构的表并后期维护、要求SQL带上拆分键,还有一些功能限制(如跨库JOIN问题)、底层存储节点用的数据库自身高可用和多副本的数据一致问题等等。不同的中间件产品能力上也有区别,互联网大厂的产品由于内部场景培育很久,做的相对成熟一些。 体验最好的分区粒度就是存储级别的Region,业务研发完全不用关心分片细节,也无法干预分片细节。当有些场景追求性能需要干预数据分布特点时就不好处理。 介入这两种策略之间的就是分区。物理上业务只要创建一个分区表,根据业务特点指定分区策略(包含分区列、拆分算法、分区数目等)。 数据复制是为了冗余和高可用,数据分区主要是为了可扩展性。不管使用哪种分区方案,业务的每条数据(记录)属于且仅属于一个分区(或分片sharding),同一个分区(分片)只会存在于一个节点。前面说了每个节点代表了一定的资源和能力。当复制和分区(分片)一起使用的时候,注意区分你看到的数据。 分区策略分区的目标是将大量数据和访问请求均匀分布在多个节点上。如果每个节点均匀承担数据和请求,那么理论上10个节点就应该能承担10倍于单节点的数据量和访问量。这个理论是忽略了复制产生的Follower副本的存在。Follower副本的空间和内存是不可能跟其他Leader副本共享的,但是计算能力(CPU)是可以的。当所有节点都提供服务的时候(多活),是计算资源最大利用。 然而如果分区是不均匀的,一些分区的数据量或者请求量会相对比较高,出现数据偏斜(skew),这个可能导致节点资源利用率和负载也不均衡。偏斜集中的数据我们又称为热点数据。避免热点数据的直接方法就是数据存储时随机分配(没有规则)给节点,缺点是读取的时候不知道去哪个分区找该记录,只有扫描所有分区了,所以这个方法意义不大。实际常用的分区策略都是有一定的规则。 这个规则可以是业务规则,也可以不是。 业务规则的分区首先是选取一个或一组列作为分区键,然后选取拆分方法。比如说根据键的范围(Range)分区,分区数量和边界时确定的(后期还可以新增分区)。好处时针对分区键的范围扫描性能会比较好。分布式数据库中间件的分库分表、分区表的分区都支持RANGE 拆分函数。各个产品拆分细节上面会有一些创新。Range分区的缺点是某些特定的访问模式会导致热点。比如说根据时间列做RANGE分区,业务写入和读写数据集中在最近的时间,就可能导致各个分区负载不均衡。这只是一个缺点,业务层面还要考虑这样做的好处。比如说删除历史分区比较快。 还有种拆分方法是散列(HASH)分区,分区数量和边界是确定的(后期可以做分区分裂)。这时各个数据的分布是否均衡就取决于各个产品实现机制。大部分做法是使用一个散列(HASH)函数对Key计算一个值,然后针分段存储。 有的产品会使用这个HASH值对分区数取模,这个方法可能引起分区数据分布不均匀(若MySQL的Key分区)。此外如果要调整分区数,则需要移动所有数据。ORACLE的HASH分区时会先选取最接近分区数的一个2的幂值,对于分区数大于这个值的分区,会从前面分区里调过来。所以ORACLE 建议HASH分区数为2的幂。M有SQL建议Key分区数为奇数时数据分布最均匀。 此外在现有分区下还可以再做一次分区,分区键和分区方法都可以不一样。通常称为两级分区。比如说分库分表时,分库和分表策略不一样就是两级分区;分区表也支持两级分区。 有业务规则的分区方案的特点就是使用上。SQL如果要性能好建议带上分区键,这样分布式数据库才可以直接定位到所访问数据所在的分片;否则,数据库就要扫描所有分区去查询数据。通常分区键只能选取一个或一组业务字段,代表的是一个业务维度,那么另外一种业务维度的SQL请求性能就会不好。个别分布式数据库产品在HASH 方法上支持两种维度的分区列,其前提是在业务构造数据时让这两个列有着内部一致的分区逻辑。 详情可以参考《说说分库分表的一个最佳实践》。 另外一种分区策略就是无业务规则的,在存储级别按块的大小切分为多个定长块(Region)。这个分区对业务而言就是透明的,所以使用体验上会相对好一些。 不过,分布式数据库里的数据分区除了存储数据还要提供读写服务。业务读写数据的SQL本身是带业务逻辑的,如果一次SQL请求访问的数据分散到多个分区,而这些分区又散落在不同的节点上,不可避免的会发生跨节点的请求。如果是多表连接,这种情形更容易出现。如果这个业务请求有事务,那这就产生了分布式事务。分布式事务解决方案有两种,强一致的两阶段提交(XA)方案和最终一致的TCC方案。详情请参考《说说数据库事务和开发(下)—— 分布式事务》。 这里主要提示跨节点的请求带来的性能衰减。当然,硬件方面万兆网卡加RDMA技术下网络延时已经缩小很多,但是当分布式数据库的请求量(QPS)非常高时,或者分布式数据库是多机房部署(比如说两地三中心)时,跨机房的网络延时还是不可忽视,跨节点的请求带来的性能衰减也会很明显。所以有业务规则的分区策略可以提供策略给业务控制自己的数据分区分布特点,非常适合做异地多活和单元化类业务。此外还有个常用的规避跨节点请求读的方法就是小表广播,即将个别没有分区的表的数据复制到其他分区所在的节点,这样相关业务数据分区的JOIN就是在本地节点内部完成。这里就看复制使用的是物理同步还是逻辑同步,以及同步的延时是否满足业务需求。 分区数量关于分区数量也需要评估。如果是无规则的分区策略,由于每个分区(分片)是定长块,那么分区数量就由总数据大小除以定长块大小,对业务也是透明的。这里总结的是有业务规则的分区的数量。 使用分区的目的是为了扩展性,具体就是能将不同分区分散多多个节点上,发挥多个节点的资源和能力。所以分区数一定要大于可用的资源节点数,为了考虑到将来分布式数据库可能会扩容,分区数应该是数倍于当前规划的节点数。这是一个总的指导思想。由于不同的分布式数据库其节点的表示方法不一样,实施的时候会略有不同。 比如说在分布式数据库中间件架构里,数据存储的节点是实例,数据分区的粒度是分表(物理表),中间还有一层分库的维度。分布式数据库实例:总物理实例数:总物理分库数:总物理分表数=1:M:N:X 。X是分区的数量,N 是总分库数。X 是固定的,如果要调整分区数,成本非常高,所以一般都是提前规划好。N 是总分库数,是2的幂。 M 是实例的数量,也建议是2的幂,决定了最大能用多少节点的资源。 N/M 的结果决定了未来能扩容的倍数。分布式数据库中间件由于数据分区落在具体的节点后就不能自由移动,其扩容方式多是对每个实例一分为二,最好的途径就是利用数据库(MySQL)自身的主从复制搭建新的备实例扩容节点数。 此外分区数还要考虑到单个分区的容量和请求量是否满足需求。即分区是否到位。这个也是需要业务评估的。在使用分区表的分区方案的分布式数据库里,分区数也是结合上面两点考虑的。 当然分区数太大了,可能会增加分布数据库内部管理成本。分区数量跟分区粒度恰好是相反关系,二者都需要取一个合适的值。 分区数量一旦确定后,调整的成本非常高,通常会引起数据重分布。有些产品可以针对特定类型的分区做分区分裂。如RANGE分区可以分裂为两个RANGE, HASH分区也可以一分为二。只要这个分区分裂的逻辑是数据库内部逻辑实现,保证数据不丢,且对业务透明的,那么风险就很低值得考虑。 分区负载均衡随着时间的推移,数据库一直在发生各种变化。如QPS增加,数据集更大,或者新增/替换机器等。无论哪种都需要将部分数据分区和相应的请求从一个节点移动到另外一个节点,这个过程称为分区的再平衡(rebalance)。业务对再平衡的要求就是平衡过程中对业务当前读写影响要可控,数据读写服务不能中断。还有一点就是为了再平衡应尽可能少的迁移数据。 前面两个要求都不难满足,最后一个要求就考验各个分区方案的灵活度了。当分区粒度是存储级别的Region时,分区迁移的粒度就是Region,这个对业务也是透明的;分区粒度是分区时,这个取决于各个产品对节点资源管理的设计。比如说有的设计可以做到只需要迁移分区就可以调整各个节点的资源利用率和负载;如果分区方案是分库分表,此时分区粒度是分表。但是数据迁移的单位通常还是实例,利用数据库原生复制能力搭建新的级联备实例,然后新老实例分别删除一半分库数据。这里就迁移了不必要的很多数据分区。 分区访问路由 ...

June 20, 2019 · 1 min · jiezi

分布式系统基础知识

1.分布式系统是什么分布式系统: 一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统,这是分布式系统,在不同的硬件,不同的软件,不同的网络,不同的计算机上,仅仅通过消息来进行通讯与协调。更细致的看这些特点又可以有:分布性、对等性、并发性、缺乏全局时钟、 故障随时会发生。 1.1分布性:最显著的特点肯定就是分布性,从简单来看,如果我们做的是个电商项目,整个项目会分成不同的功能,专业点就不同的微服务,比如用户微服务,产品微服务,订单微服务,这些服务部署在不同的tomcat中,不同的服务器中,甚至不同的集群中,整个架构都是分布在不同的地方的,在空间上是随意的,而且随时会增加,删除服务器节点,这是第一个特性。 1.2对等性:对等性是分布式设计的一个目标。分布式系统拆分了好多个服务,每个服务都可能出问题而导致整个系统出问题,因此每个服务一般都有备份,在服务异常时备份服务能顶替原来异常的服务.关键:这就要求2个服务是完全对等的,功能完全一致.比如订单服务,客户服务等,其实就是服务副本的冗余. 还有一种是数据冗余,如数据库,缓存和分布式服务一样需要有备份存在,这就是对等性. 1.3并发性:在分布式系统里面的并发就不是我们基础学习的多线程(单JVM)了,而是更高层,从多进程多JVM角度,比如多个分布式服务可能并发操作一些共享资源,如何准确并高效的协调分布式并发操作. 1.4缺乏全局时钟:在分布式系统中,节点是可能反正任意位置的,而每个位置,每个节点都有自己的时间系统,因此在分布式系统中,很难定义两个事务纠结谁先谁后,原因就是因为缺乏一个全局的时钟序列进行控制,当然,现在这已经不是什么大问题了,已经有大把的时间服务器给系统调用。 1.5故障随时发生任何一个节点都可能出现停电,死机等现象,服务器集群越多,出现故障的可能性就越大,随着集群数目的增加,出现故障甚至都会成为一种常态,怎么样保证在系统出现故障,而系统还是正常的访问者是作为系统架构师应该考虑的。 2.分布式系统协调“方法论”2.1 分布式系统带来的问题: 通信异常:通讯异常其实就是网络异常,网络系统本身是不可靠的,由于分布式系统需要通过网络进行数据传输,网络光纤,路由器等硬件难免出现问题。只要网络出现问题,也就会影响消息的发送与接受过程,因此数据消息的丢失或者延长就会变得非常普遍。网络分区:网络分区,其实就是脑裂现象。比如有个管理者与一些服务通信并协调服务,出于一些异常情况通信断了,出现了一个临时管理者,实际上原来的管理者还在,这样2个管理者做同一个工作会出现问题三态:三态其实就是成功,与失败以外的第三种状态,叫超时态。 在一个jvm中,应用程序调用一个方法函数后会得到一个明确的相应,要么成功,要么失败,而在分布式系统中,虽然绝大多数情况下能够接受到成功或者失败的相应,但一旦网络出现异常,就非常有可能出现超时,当出现这样的超时现象,网络通讯的发起方,是无法确定请求是否成功处理的。节点故障: 节点故障在分布式系统下是比较常见的问题,指的是组成服务器集群的节点会出现的宕机或“僵死”的现象,这种现象经常会发生. 2.2 CAP理论 CAP其实就是一致性,可用性,分区容错性这三个词的缩写。 C 一致性:数据在分布式环境下的多个副本之间能否保持一致性,这里的一致性更多是指强一致性;这里说的一致性和前面说的对等性其实差不多。如果能够在分布式系统中针对某一个数据项的变更成功执行后,所有用户都可以马上读取到最新的值,那么这样的系统就被认为具有【强一致性】。A 可用性:分布式系统一直处于可用状态,对于请求总是能在有限的时间内返回结果致性;这里的重点是【有限的时间】和【返回结果】,为了做到有限时间用到了缓存,负载均衡,为了返回结果考虑服务器主备.P 分区容错性:除非整个网络故障,分布式系统在任何网络或者单点故障时,仍能对外提供满足一致性和可用性的服务;CAP具体描述: 2.3. BASE理论 即使无法做到强一致性,但分布式系统可以根据自己的业务特点,采用适当的方式来使系统达到最终的一致性; BasicallyAvaliable基本可用:当分布式系统出现不可预见的故障时,允许损失部分可用性,保障系统的“基本可用”;体现在“时间上的损失”和“功能上的损失”;e.g:部分用户双十一高峰期淘宝页面卡顿或降级处理;Soft state软状态:允许系统中的数据存在中间状态,既系统的不同节点的数据副本之间的数据同步过程存在延时,并认为这种延时不会影响系统可用性;e.g:12306网站卖火车票,请求会进入排队队列;Eventually consistent最终一致性:所有的数据在经过一段时间的数据同步后,最终能够达到一个一致的状态;e.g:理财产品首页充值总金额短时不一致;分布式一致性算法:常见分布式一致性算法:2p,3p,paxos,zab算法;

June 18, 2019 · 1 min · jiezi

为什么说优秀架构师往往是一个悲观主义者

阿里妹导读:18年前,200家企业由于在事故中信息系统遭到严重破坏而永远地关闭了。这样的事故引发了后人深思,对于工程师而言,不仅要求设计的系统足够强壮,还需要具备考虑失败的能力,当失败场景悉数被考虑周全、并且结合充分的演练,一切会不会不一样?我们熟知面向对象设计和面向程序设计,阿里巴巴资深技术专家游骥洞悉行业现状,抛出了一个新模式——面向失败设计。今天,听他娓娓道来,如何在一开始的系统设计阶段就考虑到各种失败场景,把面向失败当成是系统设计的一部分,准备好从失败中恢复的策略。引言一个优秀的架构师通常都是一个悲观主义者,除了设计好能够支撑业务持续发展的优雅架构,另一个容易被忽略的重要能力在于充分考虑失败场景。如果对失败场景考虑不够充分,轻则出现业务不可用,影响用户体验和企业声誉;重则导致数据永久丢失、业务再无恢复可能。 2001 年 9 月 11 日,美国世贸中心双子大厦遭受了谁也无法预料的恐怖打击,灾难发生前约有 350 家企业在世贸大厦中工作,事故发生一年后,重返世贸大厦的企业变成了 150 家,有200 家企业由于重要信息系统的破坏,关键数据的丢失而永远关闭、消失了,其中的一家公司声称自己要恢复到灾难前的状态需要 50 年的时间。 “Everything fails, all the time”,无论是在传统软件时代还是在互联网、云时代,系统终究会在某个时间点失败,面向失败的设计理念数十年来并没有多大的变化,不同的是在分布式、云架构的互联网时代:失败将由小概率偶发事件变成常态,同时应对和处理失败的具体实现方式也大相径庭。 无所不在的失败场景单个技术点在绝大部分时间都能按照设想正常工作,但是当规模和复杂度到达一定程度,失败其实无所不在。当你的业务场景从服务企业内部的几百号员工变成面向上亿的外部用户,你不确定你的用户群会有些什么样的角色,也不知道他们会在你的系统平台上创造出什么样的业务行为;当你的技术框架从单机、一体机演进到分布式的多层、多组件架构,原本5个以内的技术组件可能变成了今天的500个,并且为了用较低的成本保持服务能力的扩展能力,你可能放弃了稳定性更好但也昂贵的商业技术、转而用开源自建来替代。 互联网业务快速发展不仅直接带来了流量、安全等不确定性,同时促使了技术架构的快速演进,使架构变得越来越复杂,这些因素都将导致失败发生的概率大幅提升。当人类的工作、生活越来越依赖互联网,一旦出现失败,造成的影响和损失将是空前巨大的。在远古时代,人类没有自来水也没有电,一切都很好;今天如果停电停水一段时间,相信很多人都会无法适应,而互联网正在逐步演变成跟水和电一样的基础设施。失败的原因多种多样,抽象来看可以分为以下几类: 硬件问题 首先,硬件是有生命周期的,它一定会老化,并且你不知道它会在什么时候坏;其次,硬件是一个实体,它存在于客观环境当中,它的状态会受外部环境干扰,比如火灾、地震等外力因素都可能导致硬件损坏;最后,所有硬件都会存在残次品,你很可能就是那个不幸者。通常情况下单个硬件出问题的概率不高,但是当有几十万的硬件设备,硬件的失败问题每天都会发生。 软件bug 即便是最优秀程序员写出来的程序,经过最优秀测试同学的严格测试后的代码,上线依然无法做到完全没有bug。互联网业务迭代往往讲究一个“快”字,以往几个月或者几年升级一次的软件程序,现在一周就需要升级一次或者多次,这大幅提升了软件出错的可能性。 配置变更错误 系统运行态的日常运维过程当中,难免会因为疏忽或者考虑不周全导致灾难。当上万名技术同学跟上百个变更系统做笛卡尔积,哪怕是6个9的可靠性,依旧无法做到万无一失。全局的流量入口、权限与安全验证体系、统一网关与接口平台等技术环节是可能促发全站不可用的重要风险点,对于影响面大的配置的变更需要尤为谨慎。 系统恶化 原本工作得很好的程序随着时间的推移可能有一天不再正常工作,举几个常见的例子:自增变量运行了很长一段时间后出现越界、缓存随着数据量的逐渐变大而出现空间不足、数据库连接池随着机器的扩容而不够用等等。千万不要认为运行良好的系统是不会出问题的,它的代码里面可能藏了定时炸弹,只是你不知道会在什么时间点爆炸。 超预期流量 某一天你的系统可能突然会承受远超过预期的每秒请求数,特别是在“中国特色”的互联网场景之下,你很难精确预估系统各个时间点的业务访问量。 外部攻击 你需要考虑各种攻击行为,包含流量攻击和安全攻击。你的系统可能随时会面临着DDOS和CC类攻击,你传输的数据可能会被盗取或者篡改。 依赖库问题 你的系统很可能会用大量的二方库或者三方库,它们对你来说是黑盒子,你不了解它们存在哪些风险,并且你无法掌控。这些库可能会存在漏洞、可能会有bug,可能会大量消耗你的系统资源,总之不要太信任它们。 依赖服务问题 你依赖的服务也一定不会100%可用,它们可能会超时,可能会失败。当依赖服务超时的时候,如果你没有很好地处理,可能会导致你自己的系统无法工作,在分布式场景下,这种失败状态会持续辐射,最终导致大面积的不可用。 如何面向失败设计作为一个悲观主义者,你需要在一开始的系统设计阶段就考虑到以上各种失败场景,把面向失败当成系统设计的一部分,并且准备好从失败中恢复的策略,这有助于更好地提升整个系统的可用性。只有你意识到事情会随着时间的推移而失败,并将这种思想融入到体系结构中,那么在失败发生的时候你才能完全不受影响或者将失败损失降到最低。面向失败的设计理念数十年来并没有多大的变化,一些好的经典原则在今天依旧被广泛运用。 冗余设计避免单点故障 硬件和软件都不可靠,环境和人都存在极大的不确定性,虽然无法避免失败场景的发生,但是可以通过冗余设计来规避局部失败对系统的影响。冗余设计避免单点故障这一策略在互联网技术架构中处处可见,比如重要的服务通常都会部署多个、数据库的主备结构、服务调用的重试机制、存储的多副本等概念都属于这一范畴。 面向失败的宏观多活架构 除了局部失败场景,你的系统可能还面临着大范围的失败场景。大范围的原因有两个:天灾,比如火灾、地震、台风、雷电等大的自然灾害可能导致大面积的基础设备被毁坏;人祸:人的失误或者刻意破坏行为有时候也会酿成大祸,如操作错误、破坏、植入有害代码和恐怖袭击。“面向失败的宏观多活架构”从宏观架构的高可用层面来解决系统的整体可用性问题,随着技术的演进,冷备、热备、两地三中心、异地多活等应对大范围失败场景的技术体系这些年频频被提起。 服务能力与依赖调用自我保护 如何来衡量一个软件系统的设计是否优良?一条很重要的衡量标准——在任何情况之下你的软件系统都应该工作在当前环境的最优状态。每个人都知道机翼是飞机的重要部件,一旦机翼出现问题,飞机很可能就会坠落。然而在二战当中,许多战斗机即便机翼千疮百孔了,依然保持着最佳战斗能力;甚至还有更夸张的情况:1983年的一次战斗机演习当中,一架飞机由于事故损失了一个机翼,这架缺少一个机翼的飞机依然保持了飞行能力、最终完成安全着陆。 软件系统由两部分构成:系统自身的代码和依赖的库以及服务。“服务能力与依赖调用自我保护”需要从这两块分别切入构建系统在任意情况都始终工作在最佳状态的能力。服务限流、系统负载保护、给依赖的服务设置超时或者资源限制等都是相应的应对策略。 为一切不可预料的情况备好预案 能够抵抗失败和从失败中快速恢复是面向失败设计的核心思想,然而即便已经做了万全的设计,也并非所有的失败场景都是系统能够自动抵御的。你需要考虑到所有的失败场景,并准备好相应的应对预案。为一切不可预料的情况备好预案才能在失败场景真正发生时做到有条不紊。做好预案需要对失败场景有全面的考虑:会发生哪些失败?失败会带来什么问题?应对策略是什么?预期的恢复时间多久?恢复后的影响面有多大?需要通知到哪些角色?等这一系列的因子构成了一个完整的预案体系。 自动化运维管控 大量的系统故障是因为人的失误造成的,即便让一个优秀的运维工程师进行一万次同样的运维操作也难免不出错。唯一的解决办法便是在运维过程当中尽可能降低人为操作的比重。系统化、白屏化是第一个阶段——将人为的操作步骤固化成系统程序,避免操作失误;自动化以及智能化是第二个阶段——将正确的决策过程也固化成智能程序,避免决策失误。同时所有的运维动作都需要遵循灰度原则,做到可灰度、可监测、可回滚,即便出现了失误也能控制好爆炸半径,并且做到快速恢复。 精细化的监控体系 面向失败设计不仅要求你的系统足够健壮,同时要求你能够在第一时间感知到失败的发生。无论是自动化的系统恢复,还是人为介入,如果你压根都不知道是哪里出问题了,一切都将束手无策。精细化的监控体系一方面能够在出现问题的时候以最快的速度将最准确的信息传递到人或者运维系统,同时它还能够展现趋势、进行提前预警。AI技术的结合使得监控领域在近几年得到了新的发展驱动力:智能监控报警、根因定位、智能预测、智能决策等能力都是学术界和工程界非常热衷的课题。 故障与攻防演练锤炼容灾应急能力 最后,即便以上工作都做好了,你也不能高枕无忧去等待失败到来。你的设计、系统、流程、技术人员等需要通过不断演练,来保障能力和进化升级。对于代价非常巨大的事件,做好前期的充分演练是非常有必要的,比如军事演练、消防演练等都属于这一范畴。而系统不可用的代价对于企业来讲很可能是无法承受的,因此需要在平时做好充分的演练:通过故障与攻防演练锤炼容灾应急能力,对面向失败的设计做好充分验证。只有当所有的失败场景都被提前演练过,当失败真正来临时才能做到胸有成竹。 本文作者: 游骥阅读原文 本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。

June 18, 2019 · 1 min · jiezi

ZooKeeper

分布式系统A distributed system is de ned as a software system that is composed of independent computing entities linked together by a computer network whose components communicate and coordinate with each other to achieve a common goal.分布式系统是由独立的计算机通过网络连接在一起,并且通过一些组件来相互交流和协作来完成一个共同的目标。分布式系统特性资源共享,例如存储空间,计算能力,数据,和服务等等扩展性,从软件和硬件上增加系统的规模并发性,多个用户同时访问性能,确保当负载增加的时候,系统想要时间不会有影响容错性,尽管一些组件暂时不可用了,整个系统仍然是可用的API抽象,系统的独立组件对用户隐藏,仅仅暴露服务ZooKeeperZookeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(Naming Service)、集群维护(Group Maintenance)等,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。ZooKeeper本身可以以单机模式安装运行,不过它的长处在于通过分布式ZooKeeper集群(一个Leader,多个Follower),基于一定的策略来保证ZooKeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。1、Zookeeper是为别的分布式程序服务的2、Zookeeper本身就是一个分布式程序(只要有半数以上节点存活,zk就能正常服务)3、Zookeeper所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统一名称服务等4、虽然说可以提供各种服务,但是zookeeper在底层其实只提供了两个功能: 管理(存储,读取)用户程序提交的数据(类似namenode中存放的metadata)并为用户程序提供数据节点监听服务;Zookeeper特性Zookeeper:一个leader,多个follower组成的集群全局数据一致:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的分布式读写,更新请求转发,由leader实施更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行数据更新原子性,一次数据更新要么成功,要么失败实时性,在一定时间范围内,client能读到最新数据Zookeeper数据结构层次化的目录结构,命名符合常规文件系统规范(类似文件系统) 每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识节点Znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)Zookeeper节点类型短暂(ephemeral)(create -e /app1/test1 “test1” 客户端断开连接zk删除ephemeral类型节点)持久(persistent) (create -s /app1/test2 “test2” 客户端断开连接zk不删除persistent类型节点)Znode目录节点PERSISTENTPERSISTENT_SEQUENTIAL(持久序列/test0000000019 )EPHEMERALEPHEMERAL_SEQUENTIAL(默认是persistent )创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护;在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序 Zookeeper应用场景数据发布与订阅(配置中心)发布与订阅模型,即所谓的配置中心,顾名思义就是发布者将数据发布到ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。 负载均衡这里说的负载均衡是指软负载均衡。在分布式环境中,为了保证高可用性,通常同一个应用或同一个服务的提供方都会部署多份,达到对等服务。而消费者就须要在这些对等的服务器中选择一个来执行相关的业务逻辑,其中比较典型的是消息中间件中的生产者,消费者负载均衡。消息中间件中发布者和订阅者的负载均衡,linkedin开源的KafkaMQ和阿里开源的 metaq都是通过zookeeper来做到生产者、消费者的负载均衡。这里以metaq为例如讲下:生产者负载均衡:metaq发送消息的时候,生产者在发送消息的时候必须选择一台broker上的一个分区来发送消息,因此metaq在运行过程中,会把所有broker和对应的分区信息全部注册到ZK指定节点上,默认的策略是一个依次轮询的过程,生产者在通过ZK获取分区列表之后,会按照brokerId和partition的顺序排列组织成一个有序的分区列表,发送的时候按照从头到尾循环往复的方式选择一个分区来发送消息。 消费负载均衡: 在消费过程中,一个消费者会消费一个或多个分区中的消息,但是一个分区只会由一个消费者来消费。MetaQ的消费策略是: 每个分区针对同一个group只挂载一个消费者。如果同一个group的消费者数目大于分区数目,则多出来的消费者将不参与消费。如果同一个group的消费者数目小于分区数目,则有部分消费者需要额外承担消费任务。在某个消费者故障或者重启等情况下,其他消费者会感知到这一变化(通过 zookeeper watch消费者列表),然后重新进行负载均衡,保证所有的分区都有消费者进行消费。 命名服务(Naming Service)命名服务也是分布式系统中比较常见的一类场景。在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址,远程对象等等——这些我们都可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。通过调用ZK提供的创建节点的API,能够很容易创建一个全局唯一的path,这个path就可以作为一个名称。阿里巴巴集团开源的分布式服务框架Dubbo中使用ZooKeeper来作为其命名服务,维护全局的服务地址列表, 点击这里查看Dubbo开源项目。在Dubbo实现中:服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。服务消费者启动的时候,订阅/dubbo/${serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入自己的URL地址。注意,所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。 另外,Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/${serviceName}目录下所有提供者和消费者的信息。 ...

June 17, 2019 · 1 min · jiezi

消息点击率翻倍的背后闲鱼无侵入可扩展IFTTT系统

一、面临问题在闲鱼生态里,用户之间会有很多种关系。其中大部分关系是由买家触发,联系到卖家,比如买家通过搜索、收藏、聊天等动作与卖家产生联系;另外一部分是平台与用户之间的关系。对这些关系分析之后我们发现这些关系中存在两个问题: 用户产生关系的层次不够丰富;现有系统只维护了一部分用户关系,包括收藏、点赞等,用户关系的层次还不够丰富。用户之间关系是单向且不够实时;在现有的玩法中,买家可以通过多种行为与卖家产生联系,但卖家不能主动与买家发生关系和互动;而且平台计算的关系都是离线的,对用户的吸引力不足。上面提到的场景经过抽象归纳之后都是同一个范式:当某个条件被满足之后,就会触发相对应的动作。这个范式是IFTTT的基本理念,而闲鱼IFTTT就是对这些问题的解决方案。 二、IFTTT概念IFTTT是一个被称为 “网络自动化神器” 的创新型互联网服务理念,它很实用而且概念很简单。IFTTT全称是 If this then that,意思是如果满足“this”条件,则触发执行“that”动作。IFTTT由三部分构成,分别为Trigger、Action和Recipe。 可以看出IFTTT本身概念并不复杂,它的真正魔力在于“由简单组成的复杂”,也就是由众多简单的IFTTT流程相互衔接成跨越整个互联网、跨越多平台、跨越多设备的状态机。 2.1、闲鱼IFTTT闲鱼IFTTT是基于闲鱼的业务场景与IFTTT理念结合后产生的,提供IFTTT标准协议封装,对业务无侵入可扩展的服务编排系统。 闲鱼IFTTT的两个特性对应上述两个问题,分别是: 多维用户关系感知多维指的是覆盖面,闲鱼IFTTT通过更多维度的挖掘,抽象并维护了更丰富的用户关系。基于用户关系数据,我们可以产出用户画像,并通过更有效的方式触达用户。 实时用户双向互动闲鱼IFTTT底层具有对用户关系大数据的高效存储和处理能力,以支持上层业务中用户关系实时处理;闲鱼IFTTT不仅支持买家到卖家关系,而且通过设计天生支持卖家到买家关系。 闲鱼IFTTT把之前平台与用户的互动、买家到卖家的联系,切换称闲鱼用户之间天然的关系互动,对用户骚扰更少且激活拉回的效果更好,我们基于这个场景设计闲鱼IFTTT的技术方案。 三、技术方案 首先按照IFTTT规范对业务进行建模,分为Channel、Trigger和Action层,其中Channel层是数据底层,将Trigger和Action关联后组成标准Recipe。 ChannelChannel层在闲鱼IFTTT的作用是保存和管理用户关系数据,Channel层定义了用户关系的元数据结构,包括关系类型、源账户和目标账户。Channel层是闲鱼IFTTT的基石,Trigger和Action均基于用户关系数据进一步抽象业务逻辑。TriggerTrigger是业务上自定义的触发事件,与业务息息相关,可能是关注的人上新、浏览宝贝降价或者是参加的百币夺宝活动开奖等。当Trigger触发后,闲鱼IFTTT会根据Trigger类型和配置的关系类型计算用户名单,并调用Action层进行处理。ActionAction层处理对象是Trigger触发后计算的用户名单,可以给名单里的用户发Push,发权益或者其他定制逻辑。Action本身是标准化、可插拔的组件,业务上可以利用Action组件对用户名单做AB测试,快速实验不同Action策略。接下来我们说一下闲鱼IFTTT详细技术方案,方案如下: 整体技术方案按照业务建模的结构图细化,补充依赖的技术组件。整体流程不再细述,针对流程中重点模块详细说明。 3.1、场景快速接入设计场景快速接入的目的是让业务对接入闲鱼IFTTT无感知,因为在最开始的设计中,场景接入是准备通过在业务逻辑里增加AOP切面,将业务数据和场景上报。但因为这种方式对业务本身有一定侵入,增加业务执行的RT而且不够灵活,最终被否决。 而现在的场景快速接入方案解决了这些问题,通过SLS接入所有应用的海量网络请求日志,记录请求的URL、参数和响应;将SLS作为Blink流计算任务的数据源;根据diamond动态下发的规则实时筛选网络请求URL和参数,把数据按照指定格式组装后上报给Channel层。 场景快速接入方案将业务逻辑与场景接入解耦,支持快速接入,灵活变更且延迟低,是针对大数据场景接入的高性能解决方案。 3.2、计算用户名单计算用户名单模块采用责任链模式设计,因为在不同Trigger场景中,业务对用户名单的计算和筛选逻辑都是不同的。通过责任链模式,将主流程与业务筛选逻辑解耦,并支持各业务灵活定制筛选逻辑,互不干扰。 3.3、PushActionAction层是闲鱼IFTTT中最重要的一环,会直接触达到用户,Action的逻辑会直接影响用户对平台的直观感受和活跃率。消息Push是Action中最常见的逻辑,更要防止用户被骚扰,PushAction逻辑如下: 敏感人群过滤;疲劳度校验;对发送人群进行AB实验;组装消息;将Action各节点日志同步到SLS,方便检索和排查问题;统计消息发送数据及点击数据,为业务后续决策提供依据;3.3.1、疲劳度疲劳度是防止用户被骚扰的关键,我们针对疲劳度进行了分层设计,分为三层,第一层为用户级别疲劳度,控制一个用户在一个周期内收到消息数量;第二层是业务维度,控制用户在一个周期内收到某个业务的消息数量;第三层是目标级别,控制用户在一个周期内收到同一个发送者消息数量。 在业务维度层面,支持灵活控制多个业务联合疲劳度,保证用户不会被消息过度骚扰。 3.4、用户关系存储用户关系数据是闲鱼IFTTT的基石,它的特点是存储量级大,达到TB级别;而且对存储和查询的性能要求高,TPS和QPS的峰值都在一万以上。经过调研,我们发现集团内部开发的Lindorm可以满足需求。 Lindorm是阿里内部基于Hbase自研的高性能KV存储数据库,对Hbase的性能和稳定性均有一定优化。闲鱼IFTTT采用Lindorm作为用户关系数据存储,经性能测试验证数据读取QPS达到7万,数据存储TPS在10万以上。Lindorm本身性能优异,为闲鱼IFTTT高性能奠定基础。 四、效果验证闲鱼IFTTT自上线以来,已支持关注上新、浏览宝贝降价和租房小区上新等多个业务场景,提供买卖双方实时双向互动能力,平均每天处理关系数据数亿条,处理Trigger量达到上千万,处理Action量达到亿级别,消息点击率较离线push提高1倍以上。 闲鱼IFTTT目前支持的是用户互动场景,后续我们将结合闲鱼自身业务特点,对IFTTT进行更高维度抽象,封装标准Recipe接口,将闲鱼IFTTT打造成提供流程编排、管理能力的服务平台。 在我看来,IFTTT从2010年推出以来,在国外有很大的热度,在互联网和物联网领域都有专门的公司和团队在研发,IFTTT的概念虽然简单,却通过标准化协议满足用户的强需求-让各种互联网产品为用户服务。这其实也给我们互联网从业者一些思考:在新机遇面前,究竟是快速投入比较重要还是抽象标准协议解决一类问题更加有效? 五、名词注解SLS:https://cn.aliyun.com/product/slsDiamond:阿里内部研发的持久配置管理中间件;Blink:https://data.aliyun.com/product/sc?spm=5176.10695662.1131226.1.bf495006EWuVABMetaQ:阿里内部研发的分布式、队列模型的消息中间件;Lindorm:阿里内部基于HBase研发的新一代分布式NoSQL数据库,阿里云类似产品:https://www.aliyun.com/product/ots?spm=a2c4g.11174283.cwnn_jpze.59.2f5a15c3NH30me;Tair:阿里内部研发的高性能、分布式、可扩展、高可靠的Key-Value结构存储系统; 本文作者:闲鱼技术-剑辛阅读原文 本文为云栖社区原创内容,未经允许不得转载。

June 17, 2019 · 1 min · jiezi

消息点击率翻倍的背后闲鱼无侵入可扩展IFTTT系统

一、面临问题在闲鱼生态里,用户之间会有很多种关系。其中大部分关系是由买家触发,联系到卖家,比如买家通过搜索、收藏、聊天等动作与卖家产生联系;另外一部分是平台与用户之间的关系。对这些关系分析之后我们发现这些关系中存在两个问题: 用户产生关系的层次不够丰富;现有系统只维护了一部分用户关系,包括收藏、点赞等,用户关系的层次还不够丰富。用户之间关系是单向且不够实时;在现有的玩法中,买家可以通过多种行为与卖家产生联系,但卖家不能主动与买家发生关系和互动;而且平台计算的关系都是离线的,对用户的吸引力不足。上面提到的场景经过抽象归纳之后都是同一个范式:当某个条件被满足之后,就会触发相对应的动作。这个范式是IFTTT的基本理念,而闲鱼IFTTT就是对这些问题的解决方案。 二、IFTTT概念IFTTT是一个被称为 “网络自动化神器” 的创新型互联网服务理念,它很实用而且概念很简单。IFTTT全称是 If this then that ,意思是如果满足“this”条件,则触发执行“that”动作。IFTTT由三部分构成,分别为Trigger、Action和Recipe。 可以看出IFTTT本身概念并不复杂,它的真正魔力在于“由简单组成的复杂”,也就是由众多简单的IFTTT流程相互衔接成跨越整个互联网、跨越多平台、跨越多设备的状态机。 2.1、闲鱼IFTTT闲鱼IFTTT是基于闲鱼的业务场景与IFTTT理念结合后产生的,提供IFTTT标准协议封装,对业务无侵入可扩展的服务编排系统。 闲鱼IFTTT的两个特性对应上述两个问题,分别是: 多维用户关系感知多维指的是覆盖面,闲鱼IFTTT通过更多维度的挖掘,抽象并维护了更丰富的用户关系。基于用户关系数据,我们可以产出用户画像,并通过更有效的方式触达用户。 实时用户双向互动闲鱼IFTTT底层具有对用户关系大数据的高效存储和处理能力,以支持上层业务中用户关系实时处理;闲鱼IFTTT不仅支持买家到卖家关系,而且通过设计天生支持卖家到买家关系。 闲鱼IFTTT把之前平台与用户的互动、买家到卖家的联系,切换称闲鱼用户之间天然的关系互动,对用户骚扰更少且激活拉回的效果更好,我们基于这个场景设计闲鱼IFTTT的技术方案。 三、技术方案 首先按照IFTTT规范对业务进行建模,分为Channel、Trigger和Action层,其中Channel层是数据底层,将Trigger和Action关联后组成标准Recipe。 ChannelChannel层在闲鱼IFTTT的作用是保存和管理用户关系数据,Channel层定义了用户关系的元数据结构,包括关系类型、源账户和目标账户。Channel层是闲鱼IFTTT的基石,Trigger和Action均基于用户关系数据进一步抽象业务逻辑。TriggerTrigger是业务上自定义的触发事件,与业务息息相关,可能是关注的人上新、浏览宝贝降价或者是参加的百币夺宝活动开奖等。当Trigger触发后,闲鱼IFTTT会根据Trigger类型和配置的关系类型计算用户名单,并调用Action层进行处理。ActionAction层处理对象是Trigger触发后计算的用户名单,可以给名单里的用户发Push,发权益或者其他定制逻辑。Action本身是标准化、可插拔的组件,业务上可以利用Action组件对用户名单做AB测试,快速实验不同Action策略。接下来我们说一下闲鱼IFTTT详细技术方案,方案如下: 整体技术方案按照业务建模的结构图细化,补充依赖的技术组件。整体流程不再细述,针对流程中重点模块详细说明。 3.1、场景快速接入设计场景快速接入的目的是让业务对接入闲鱼IFTTT无感知,因为在最开始的设计中,场景接入是准备通过在业务逻辑里增加AOP切面,将业务数据和场景上报。但因为这种方式对业务本身有一定侵入,增加业务执行的RT而且不够灵活,最终被否决。 而现在的场景快速接入方案解决了这些问题,通过SLS接入所有应用的海量网络请求日志,记录请求的URL、参数和响应;将SLS作为Blink流计算任务的数据源;根据diamond动态下发的规则实时筛选网络请求URL和参数,把数据按照指定格式组装后上报给Channel层。 场景快速接入方案将业务逻辑与场景接入解耦,支持快速接入,灵活变更且延迟低,是针对大数据场景接入的高性能解决方案。 3.2、计算用户名单计算用户名单模块采用责任链模式设计,因为在不同Trigger场景中,业务对用户名单的计算和筛选逻辑都是不同的。通过责任链模式,将主流程与业务筛选逻辑解耦,并支持各业务灵活定制筛选逻辑,互不干扰。 3.3、PushActionAction层是闲鱼IFTTT中最重要的一环,会直接触达到用户,Action的逻辑会直接影响用户对平台的直观感受和活跃率。消息Push是Action中最常见的逻辑,更要防止用户被骚扰,PushAction逻辑如下: 敏感人群过滤;疲劳度校验;对发送人群进行AB实验;组装消息;将Action各节点日志同步到SLS,方便检索和排查问题;统计消息发送数据及点击数据,为业务后续决策提供依据;3.3.1、疲劳度疲劳度是防止用户被骚扰的关键,我们针对疲劳度进行了分层设计,分为三层,第一层为用户级别疲劳度,控制一个用户在一个周期内收到消息数量;第二层是业务维度,控制用户在一个周期内收到某个业务的消息数量;第三层是目标级别,控制用户在一个周期内收到同一个发送者消息数量。 在业务维度层面,支持灵活控制多个业务联合疲劳度,保证用户不会被消息过度骚扰。 3.4、用户关系存储用户关系数据是闲鱼IFTTT的基石,它的特点是存储量级大,达到TB级别;而且对存储和查询的性能要求高,TPS和QPS的峰值都在一万以上。经过调研,我们发现集团内部开发的Lindorm可以满足需求。 Lindorm是阿里内部基于Hbase自研的高性能KV存储数据库,对Hbase的性能和稳定性均有一定优化。闲鱼IFTTT采用Lindorm作为用户关系数据存储,经性能测试验证数据读取QPS达到7万,数据存储TPS在10万以上。Lindorm本身性能优异,为闲鱼IFTTT高性能奠定基础。 四、效果验证闲鱼IFTTT自上线以来,已支持关注上新、浏览宝贝降价和租房小区上新等多个业务场景,提供买卖双方实时双向互动能力,平均每天处理关系数据数亿条,处理Trigger量达到上千万,处理Action量达到亿级别,消息点击率较离线push提高1倍以上。 闲鱼IFTTT目前支持的是用户互动场景,后续我们将结合闲鱼自身业务特点,对IFTTT进行更高维度抽象,封装标准Recipe接口,将闲鱼IFTTT打造成提供流程编排、管理能力的服务平台。 在我看来,IFTTT从2010年推出以来,在国外有很大的热度,在互联网和物联网领域都有专门的公司和团队在研发,IFTTT的概念虽然简单,却通过标准化协议满足用户的强需求-让各种互联网产品为用户服务。这其实也给我们互联网从业者一些思考:在新机遇面前,究竟是快速投入比较重要还是抽象标准协议解决一类问题更加有效? 五、名词注解SLS:https://cn.aliyun.com/product/slsDiamond:阿里内部研发的持久配置管理中间件;Blink:https://data.aliyun.com/product/sc?spm=5176.10695662.1131226.1.bf495006EWuVABMetaQ:阿里内部研发的分布式、队列模型的消息中间件;Lindorm:阿里内部基于HBase研发的新一代分布式NoSQL数据库,阿里云类似产品:https://www.aliyun.com/product/ots?spm=a2c4g.11174283.cwnn_jpze.59.2f5a15c3NH30me;Tair:阿里内部研发的高性能、分布式、可扩展、高可靠的Key-Value结构存储系统; 本文作者:闲鱼技术-剑辛原文链接 本文为云栖社区原创内容,未经允许不得转载。

June 14, 2019 · 1 min · jiezi

从遇见到信任-Apache-Dubbo-的毕业之旅

所谓信任,就是多一次机会。 2018年2月16日,Apache Dubbo 加入 Apache 基金会孵化器。 ... 2019年5月16日,Apache 软件基金会董事会决议通过了 Apache Dubbo 的毕业申请,这意味着 Apache Dubbo 正式成为 Apache 的顶级项目。5月21日,Apache 官方发布了这一消息。这也是 阿里巴巴微服务 继 Apache RocketMQ 后的又一个 Apache 顶级项目。 What is Dubbo ?Apache Dubbo 起初的定位是一款轻量级、高性能的服务框架,自 2012 年开源以来,深受国内开发者的喜爱,并被国内许多企业选型作为服务化改造的方案首选和微服务架构的基石之一。其主要功能是: 提供基于RPC的高性能接口,对用户透明。智能负载均衡:支持多种开箱即用的负载均衡策略,可以感知下游服务状态,从而减少总体延迟并提高系统吞吐量。自动服务注册和发现:支持多个服务注册表,可以立即在线/离线检测服务。高可扩展性:微内核和插件设计确保可以通过协议,传输和序列化等核心功能轻松扩展第三方实施。运行时流量路由:可以在运行时配置,以便根据不同的规则路由流量,这样可以轻松支持蓝绿部署,数据中心感知路由等功能。可视化服务治理:为服务治理和维护提供丰富的工具,例如查询服务元数据,运行状况和统计信息。Dubbo meets Apache2018 年 2 月,阿里巴巴将 Apache Dubbo 捐献给 Apache 软件基金会,得到了社区广泛的好评。 在这1年多的孵化过程中,Dubbo 社区: 持续迭代,共计发布11个版本;多元化治理,新增了6位 PPMC Member (孵化项目管理管理会成员),他们来自阿里巴巴、京东、美团点评、去哪儿、网易、微店、有赞等企业;并发展了15位项目提交者(对 Dubbo 项目具有提交权限),他们来自阿里巴巴、曹操科技、滴滴出行、国美金融、韩都衣舍、华为、京东、Keep、科大讯飞、美团点评、去哪儿、融贯电商、网联清算、网易、微店、亚信安全等10多家公司;构建多元化社区,Dubbo 主项目的贡献者从70+提升到目前的200位;用户多元化,阿里巴巴、当当、滴滴、海尔、去哪儿、网联清算、网易考拉、微店、中国电信、中国工商银行、中国人寿、中国银联等140多家公司在 GitHub 上报告了已将 Apache Dubbo 运用于生产环境中 ;GitHub 上的 star 数从入住孵化器前的17520增加到26400+,fork 数更是达到了17500+,fork 数排在所有Java 项目中的第三位;孵化过程中,Dubbo 社区的多样性得到了极大的发展,并不断演进核心和丰富生态,旨在为开发者们构建微服务和云原生支撑的基石。 ...

June 14, 2019 · 2 min · jiezi

一键托管阿里云全链路追踪服务正式商用成本仅自建15或更少

随着互联网架构的扩张,分布式系统变得日趋复杂,越来越多的组件开始走向分布式化,如微服务、消息收发、分布式数据库、分布式缓存、分布式对象存储、跨域调用,这些组件共同构成了繁杂的分布式网络。 在一次800多人的开发者调研中,当回答“现阶段构建一个高可用的分布式系统,您遇到的三个最大的难题是什么?”时,57%的开发者选择了全链路追踪。 6月12日,阿里云发布了链路追踪服务 Tracing Analysis,提供分布式系统的全链路追踪能力,帮助客户快速发现和定位分布式系统下的各类性能瓶颈,成本仅自建链路追踪系统的1/5甚至更少。 微服务架构下的分布式应用架构虽然满足了应用横向扩展需求,但是如何进行分布式应用诊断成为挑战。虽然,业内有链路追踪相关的开源解决方案,但存在着研发投入较高、自建成本较高、技术风险较大、运维难度较大的挑战。 链路追踪 Tracing Analysis源自阿里巴巴内部的经过大规模实战验证过的 EagleEye,基于 Opentracing 标准,全面兼容开源社区,可实现 Jaeger, Zipkin 和 Skywalking等开源方案在阿里云上的托管,客户无需搭建基础设施,节省运维投入和技术风险。同时,支持多语言客户端将应用的链路数据上报至链路追踪控制台,实现链路追踪的目的。 据介绍,链路追踪 Tracing Analysis 可用于链路拓扑分析,慢请求、异常请求、流量异常的问题发现和定位,并可以根据业务Tag 对业务进行统计。以某教育行业客户为例,链路追踪 Tracing Analysis 帮助客户将异常请求数从原先的3%降低到0.1%,排查5个以上线上问题。 此外,链路追踪 Tracing Analysis可帮助用户收集所有分布式微服务应用和相关PaaS产品的分布式调用信息,查看应用的依赖路径,用于业务分析和稳定性评估。以某金融行业客户为例,链路追踪 Tracing Analysis 帮助客户将将应用的平均响应时间从2秒降低到500毫秒。 值得注意的是,链路追踪 Tracing Analysis 省去了客户自建基础设施的本地存储费用,仅通过云端日志存储收取存储费用,总体的机器成本是自建全链路追踪系统的1/5或更少,并提供了每天1000请求数的免费使用额度。 目前,阿里云链路追踪 Tracing Analysis已应用于金融、游戏、教育、零售、人工智能等多个行业,帮助开发者高效的分析和诊断分布式应用架构下的性能瓶颈。 Q&A: Q1:可以通过 API 拉取链路追踪的数据吗?A1:支持,收集的链路可以通过OpenAPI的方式获取,也可以嵌入链路追踪的页面展示,也可以直接在日志服务中查看。 Q2:非阿里云服务,可以接入链路追踪?A2:链路是追踪是开放的,只要客户的应用可以访问公网,就可以接入,和有没部署在阿里云上没关系。 Q3:埋点对性能的影响有相关分析么?A3:埋点数据是异步批量上报的,会对性能有影响有限,一般在1%左右,主要看埋点的量,埋的多会影响大一点。从目前的压测数据来看,对性能影响比较小。 本文作者:中间件小哥原文链接  本文为云栖社区原创内容,未经允许不得转载。

June 13, 2019 · 1 min · jiezi

关于分布式集群负载均衡微服务的关系说明

https://www.cnblogs.com/wmqia...

June 13, 2019 · 1 min · jiezi

一文读懂架构整洁之道附知识脉络图

程序的世界飞速发展,今天所掌握的技能可能明年就过时了,但有一些东西是历久弥新,永远不变的,掌握了这些,在程序的海洋里就不会迷路,架构思想就是这样一种东西。 本文是《架构整洁之道》的读书笔记,文章从软件系统的价值出发,认识架构工作的价值和目标, 依次了解架构设计的基础、指导思想(设计原则)、组件拆分的方法和粒度、组件之间依赖设计、组件边界多种解耦方式以及取舍、降低组件之间通信成本的方法,从而在做出正确的架构决策和架构设计方面,给出作者自己的解读。 阿里巴巴中间件微信公众号对话框,发送“架构”,可获取《架构整洁之道》知识脉络图。直接访问,点击这里。 一、软件系统的价值架构是软件系统的一部分,所以要明白架构的价值,首先要明确软件系统的价值。软件系统的价值有两方面,行为价值和架构价值。 行为价值是软件的核心价值,包括需求的实现,以及可用性保障(功能性 bug 、性能、稳定性)。这几乎占据了我们90%的工作内容,支撑业务先赢是我们工程师的首要责任。如果业务是明确的、稳定的,架构的价值就可以忽略不计,但业务通常是不明确的、飞速发展的,这时架构就无比重要,因为架构的价值就是让我们的软件(Software)更软(Soft)。可以从两方面理解: 当需求变更时,所需的软件变更必须简单方便。变更实施的难度应该和变更的范畴(scope)成等比,而与变更的具体形状(shape)无关。当我们只关注行为价值,不关注架构价值时,会发生什么事情?这是书中记录的一个真实案例,随着版本迭代,工程师团队的规模持续增长,但总代码行数却趋于稳定,相对应的,每行代码的变更成本升高、工程师的生产效率降低。从老板的视角,就是公司的成本增长迅猛,如果营收跟不上就要开始赔钱啦。 可见架构价值重要性,接下来从著名的紧急重要矩阵出发,看我们如何处理好行为价值和架构价值的关系。 重要紧急矩阵中,做事的顺序是这样的:1.重要且紧急 > 2.重要不紧急 > 3.不重要但紧急 > 4.不重要且不紧急。实现行为价值的需求通常是 PD 提出的,都比较紧急,但并不总是特别重要;架构价值的工作内容,通常是开发同学提出的,都很重要但基本不是很紧急,短期内不做也死不了。所以行为价值的事情落在1和3(重要且紧急、不重要但紧急),而架构价值落在2(重要不紧急)。我们开发同学,在低头敲代码之前,一定要把杂糅在一起的1和3分开,把我们架构工作插进去。 二、架构工作的目标前面讲解了架构价值,追求架构价值就是架构工作的目标,说白了,就是用最少的人力成本满足构建和维护该系统的需求,再细致一些,就是支撑软件系统的全生命周期,让系统便于理解、易于修改、方便维护、轻松部署。对于生命周期里的每个环节,优秀的架构都有不同的追求: 开发阶段:组件不要使用大量复杂的脚手架;不同团队负责不同的组件,避免不必要的协作。部署阶段:部署工作不要依赖成堆的脚本和配置文件;组件越多部署工作越繁重,而部署工作本身是没有价值的,做的越少越好,所以要减少组件数量。运行阶段:架构设计要考虑到不同的吞吐量、不同的响应时长要求;架构应起到揭示系统运行的作用:用例、功能、行为设置应该都是对开发者可见的一级实体,以类、函数或模块的形式占据明显位置,命名能清晰地描述对应的功能。维护阶段:减少探秘成本和风险。探秘成本是对现有软件系统的挖掘工作,确定新功能或修复问题的最佳位置和方式。风险是做改动时,可能衍生出新的问题。三、编程范式其实所谓架构就是限制,限制源码放在哪里、限制依赖、限制通信的方式,但这些限制比较上层。编程范式是最基础的限制,它限制我们的控制流和数据流:结构化编程限制了控制权的直接转移,面向对象编程限制了控制权的间接转移,函数式编程限制了赋值,相信你看到这里一定一脸懵逼,啥叫控制权的直接转移,啥叫控制权的间接转移,不要着急,后边详细讲解。 这三个编程范式最近的一个也有半个世纪的历史了,半个世纪以来没有提出新的编程范式,以后可能也不会了。因为编程范式的意义在于限制,限制了控制权转移限制了数据赋值,其他也没啥可限制的了。很有意思的是,这三个编程范式提出的时间顺序可能与大家的直觉相反,从前到后的顺序为:函数式编程(1936年)、面向对象编程(1966年)、结构化编程(1968年)。 1.结构化编程 结构化编程证明了人们可以用顺序结构、分支结构、循环结构这三种结构构造出任何程序,并限制了 goto 的使用。遵守结构化编程,工程师就可以像数学家一样对自己的程序进行推理证明,用代码将一些已证明可用的结构串联起来,只要自行证明这些额外代码是确定的,就可以推导出整个程序的正确性。 前面提到结构化编程对控制权的直接转移进行了限制,其实就是限制了 goto 语句。什么叫做控制权的直接转移?就是函数调用或者 goto 语句,代码在原来的流程里不继续执行了,转而去执行别的代码,并且你指明了执行什么代码。为什么要限制 goto 语句?因为 goto 语句的一些用法会导致某个模块无法被递归拆分成更小的、可证明的单元。而采用分解法将大型问题拆分正是结构化编程的核心价值。 其实遵守结构化编程,工程师们也无法像数学家那样证明自己的程序是正确的,只能像物理学家一样,说自己的程序暂时没被证伪(没被找到bug)。数学公式和物理公式的最大区别,就是数学公式可被证明,而物理公式无法被证明,只要目前的实验数据没把它证伪,我们就认为它是正确的。程序也是一样,所有的 test case 都通过了,没发现问题,我们就认为这段程序是正确的。 2.面向对象编程 面向对象编程包括封装、继承和多态,从架构的角度,这里只关注多态。多态让我们更方便、安全地通过函数调用的方式进行组件间通信,它也是依赖反转(让依赖与控制流方向相反)的基础。 在非面向对象的编程语言中,我们如何在互相解耦的组件间实现函数调用?答案是函数指针。比如采用C语言编写的操作系统中,定义了如下的结构体来解耦具体的IO设备, IO 设备的驱动程序只需要把函数指针指到自己的实现就可以了。 struct FILE { void (*open)(char* name, int mode); void (*close)(); int (*read)(); void (*write)(char); void (*seek)(long index, int mode);}这种通过函数指针进行组件间通信的方式非常脆弱,工程师必须严格按照约定初始化函数指针,并严格地按照约定来调用这些指针,只要一个人没有遵守约定,整个程序都会产生极其难以跟踪和消除的 Bug。所以面向对象编程限制了函数指针的使用,通过接口-实现、抽象类-继承等多态的方式来替代。 前面提到面向对象编程对控制权的间接转移进行了限制,其实就是限制了函数指针的使用。什么叫做控制权的间接转移?就是代码在原来的流程里不继续执行了,转而去执行别的代码,但具体执行了啥代码你也不知道,你只调了个函数指针或者接口。 ...

June 12, 2019 · 1 min · jiezi

如何将深度学习训练速度提升一百倍PAISoar-来了

阿里妹导读:得力于数据规模增长、神经网络结构的演进和计算能力的增强,深度学习的图像处理、语音识别等领域取得了飞速发展。随着训练数据规模和模型复杂度的不断增大,如何充分利用分布式集群的计算资源加快训练速度,提升业务支持能力成为用户非常关注的问题。今天,我们就来分享阿里工程师的实践成果:将深度学习模型的大规模分布式训练框架 PAISoar应用于绿网模型(多层CNN网络)后,绿网模型在128 GPU卡上取得101倍的计算加速比,效果显著。1. 概述近几年来深度学习发展迅速,图像处理、语音识别等领域都取得了飞速发展。例如在图片识别上,神经网络结构快速演进,分类的网络结构从 AlexNet、VGG、Inception V1 发展到了 Inception V4、Inception-ResNet、SENet。随着模型层次越来越深,参数越来越多,模型能力也越来越强,ImageNet 数据集 Top-5 的错误率越来越低,目前降到了2.25%(人眼5.1%)。 随着模型复杂度不断增长、训练样本的指数级增长,分布式进行高效并行的神经网络训练已经变得越发重要。在社区版 Tensorflow 中,分布式训练是基于 Parameter Server 模式进行多机训练的。在这种训练方式下训练任务通常会遇到以下挑战: Variable placement 策略,常用的 replica_device_setter 的策略是 round-robin over all ps tasks,这种策略并没有考虑 Variable 大小,会导致参数分配不均衡,某些 ps 上分配的 Variable size 大就会成为通信瓶颈;多个 Worker 访问同一个 PS 节点时,受 PS 节点带宽限制和 TCP 的拥塞窗口控制,会导致通信效率大幅降低,并且规模越大,效率越差;分布式扩展后,模型需要精细调参才能收敛,需要用户有丰富的调参经验。对此,我们基于 PAI Tensorflow 研发了针对于深度学习模型的高速分布式训练框架 PAISoar,从硬件到软件打造一套分布式训练场景 E2E 的解决方案: 在硬件上,我们和 AIS 网络团队一起搭建了集团内部第一套基于 RoCE 的大规模 RDMA 集群,并针对于深度学习场景进行了相应的参数调优,支持低延迟、高吞吐的无损传输网络;在软件上,我们基于 Ring AllReduce 算法在 RDMA 网络上实现了高度优化的 PAISoar 分布式训练框架,通过软硬件一体的深度优化大大提高了多机的计算加速比;在 API 层面,我们提供了简化用户构建分布式 TF 模型训练的ReplicatedVarsOptimizer,极大地方便了将单机模型扩展成分布式模型,降低了用户构建分布式TF训练代码的难度,同时提供支持 warm up 的 learning rate 动态调节方法,帮助模型训练更容易的收敛。PAISoar 在 Tensorflow 官方 benchmarks 模型上取得了非常不错的加速效果。同时我们还和安全部团队合作,将该研发成果成功的在安全部图像模型业务上落地。安全部的绿网模型训练样本280万张图片,单机两卡训练需要12天才能收敛,因此有着非常强的分布式训练需求,希望能达到一天内完成训练,提升模型迭代能力。借助于 PAISoar,绿网模型分布式训练取得非常明显的加速效果,模型收敛时间从原先的12天降低到目前的一天以内,大大加速了业务的快速迭代。 ...

June 12, 2019 · 3 min · jiezi

NoSQL-数据库不应该放弃-Consistency

本文发于infoq,https://www.infoq.cn/article/rhzs0KI2G*Y2r9PMdeNv 。转回自己的博客。 谈到 NoSQL,一定会提及一致性(Consistency),按照 CAP 定理,有些 NoSQL 数据库放弃了一致性,但是 NoSQL 放弃是必然的选择吗? 从 1970’s,关系型数据库(RDB,Relational Database)被发明以来,关系型数据库就是构建应用的通常的选择。关系型数据库对用户提供 ACID 保证,非常方便开发者使用。从 1990’s 开始,NoSQL 系统开始出现。NoSQL 系统是一类对立于关系数据库的数据库系统,他们从架构上放弃了传统的关系型数据库的的关系模型和 SQL 的接口。 与 NoSQL 系统相伴而来的 2 个词是 BASE 和 CAP,这 2 个词对分布式系统有着非常深远的影响。我相信就是在这 2 个词的影响下,很多 NoSQL 系统从架构的初始就放弃了一致性(consistency)选择了一种最终一致性(Eventual consistency)和可用性 (Availability)。虽然我非常认同 CAP 和 BASE 这 2 个词,但是我不认为在 CAP 和 BASE 的作用下,NoSQL 系统选择放弃一致性是一个必然的事情。 首先来回顾一下 CAP 和 BASE 这 2 个概念的历史。这 2 个概念都是由 Eric Brewer 提出的,Brewer 目前是 Google 公司的基础设施部门(Infrastructure)的副总裁(VP,Vice President)。在 1997 年,在 SOSP(Symposium on Operating Systems Principles) 上,名为的演讲 [1] 总结了 Brewer 等人的近期工作,演讲中说他们正在工作的集群服务并没有采用当时公认的具有 ACID 特性的关系型数据库作为架构,而是在架构上放弃了关系型数据库的 ACID 特性。并且为他们的这个架构选择构造了一个新的词 BASE,BASE 这个词的选择有刻意为之成分,ACID 在英语里有酸性的意思,而 BASE 有碱性的意思,很明显 BASE 是与?ACID 对立的。 ...

June 12, 2019 · 2 min · jiezi

360自研分布式海量小文件存储系统的设计与实现

背景近年来,公司业务发展迅猛,为数众多的业务场景产生了大量的图片,文档,音频,视频等非结构化数据,尤其是随着移动互联网、AI、IoT技术的成熟和应用市场的全面爆发,大量智能硬件设备将会生成更大规模的非结构化多媒体数据。如此大量的小文件如何存储,问题应运而生。传统存储厂商出售的存储服务价格昂贵,公有云厂商对具体业务场景的定制化改造略有欠缺,因此,我们决定自研小文件存储服务。 NebulasFs简介曾经关注小文件存储技术的同学可能阅读过Facebook发表的那篇关于海量小图片存储系统Haystack的论文(Finding a needle in Haystack: Facebook’s photo storage),Haystack通过合并多个小文件成一个大文件、以减少文件数量的方式解决了普通文件系统在存储数量巨大的小文件时的问题:获取一次文件多次读取元数据信息、文件访问的“长尾”效应导致大量文件元数据不容易缓存等。基于在Haystack的论文中得到的借鉴和参考,我们研发了自己的分布式小文件存储系统——NebulasFs。它是一个分布式、高可用、高可靠、持久化小文件存储系统,可以存储数以百亿的小文件。 架构设计从分布式角色上划分,可以分为Master和Datanode两个大的角色。 其中,Master负责集群的元数据存储、集群管理、任务调度等工作,它的数据一致性目前由外部一致性工具(ETCD等)实现。Master是一个主多个备。 Datanode是面向用户的,它主要负责数据存储和用户请求的路由、分发。Datanode节点包括存储Volume文件和Proxy模块。如下图所示: 用户的请求可以请求任意一个Datanode节点,节点的Proxy模块会代理用户请求到正确的数据存储节点,并返回给用户结构。对于多个副本的写请求,Proxy模块会按照副本的一致顺序并行写入直至全部成功后返回。对于读请求只读取第一个副本。 NebulasFs功能为了在存储容量、一致性、可用性等方面有更好的提升来满足海量小文件存储的需求,相对于Haystack论文,我们在接口服务、分布式架构方面做了更多的优化,主要体现在以下方面: 一、提供给用户使用的服务接口简单、轻量、通用NebulasFs提供给用户Http Restful接口,协议更简单,使用更方便,用户可以通过简单的PUT,GET等操作上传和下载文件。用户无需使用定制的客户端,更加轻量级。 二、用户请求全代理、自动路由我们知道,Datanode具有数据存储的功能,可是对于数量众多的Datanode来说,用户要想知道哪些数据存储在哪个Datanode上是需要先从Master 拿到数据路由的元数据才知道,这增加了用户请求的复杂度。我们在Datanode上增加了请求代理、路由模块把用户的请求自动代理、路由到正确的Datanode上,使得用户一次请求既能获取数据。 三、多租户,提供租户资源隔离机制,避免相互影响一个集群提供的服务可能有多个用户来使用,为了避免互相影响,NebulasFs抽象出了资源池的概念,不同的资源池物理上是分布在不同的硬件之上,资源池在机器维度上不交叉,可以有效的做到资源的隔离。不同的用户可以分布在不同的资源池也可以共享资源池,这需要管理员提前做好规划。资源池类型是多样的,它的范围可能是跨数据中心的,也可能是跨机柜,也可能是在一个机柜之内的。根据不同的物理硬件性能和数据副本存储冗余需求,对不同类型的数据存储需求也需要提前规划。 四、可定制的数据多副本存储方案,数据无丢失、多种故障域组合为了提供可用性,保证写入数据不丢失,文件数据一般都会做容灾存储大于1的副本数量,以便在发生不可恢复的硬件故障时保证数据可用性以及用作之后的自动补齐副本数量。不同重要级别的数据和不同级别故障类型决定了使用不同级别的存储方案。NebulasFs预先定义了5个级别的故障域,分别是:数据中心、机柜列、机柜、机器、磁盘。要求可用性较高的数据存储时使用跨数据中心做容灾副本,以便在整个数据中心不可用时使用另外一个数据中心的数据。要求没那么高的数据可以在做容灾副本策略的时候选择跨机柜存储即可,使得即便在边沿交换机故障后也可用。 NebulasFs故障域和资源隔离池之间的关系如下: S代表服务器,R-1, R-2是属于数据中心DC-1的两个机柜,R-3, R42是属于数据中心DC-2的两个机柜。Pool-1是跨机柜故障域的资源隔离池,Pool-2是跨数据中心故障域的资源池,Pool-3是跨服务器故障域的资源池。 NebulasFs 故障域逻辑和物理概念对应如下: 其中上半部分是逻辑概念,下半部分是物理概念。用户及请求均与逻辑概念相关,管理运维涉及物理概念相关。一个用户可以对应一个或者多个Collection, 一个Collection对应多个Volume, 每个Volume是存储在DataNode上的文件(有几个副本就有几个文件)。一般一个DataNode对应服务器上的一块硬盘。一台服务器上有多个DataNode。服务器(Server)的上层是机柜(Rack)、一排机柜(Row)和数据中心(DataCenter)。 五、自动化扩容和再平衡扩容分为存储容量不足进行扩容和请求流量过载进行的扩容。由于容量不足的扩容后无需再平衡,只有请求流量大扩容后需要做数据再平衡。再平衡是按照容灾副本数等策略进行的,按照策略添加的Datanode会自动注册到Master上,Master按照预定的规则进行协调再平衡。 两种扩容情况如下: 六、自动化副本修复补齐一定规模的集群故障可能会变的比较频繁,在我们的系统中故障很大程度上意味着数据副本的丢失,人工补齐数据副本工作量较大,因此自动化补齐副本就成了一个比较重要的功能。自动化补齐副本是靠Master发现副本缺失和协调补齐的。在补齐的过程中数据副本都会变成只读。过程如下图: 整个自动化副本补齐如下图所示: 由于硬盘故障,数据节点 2 和 3 上的Volume 3 和 6 副本丢失,自动补齐自动把这两个副本补齐到数据节点 4  和 5 上,并加入到集群中。 小 结到目前为止,NebulasFs在内部已经使用了近一年的时间。除此之外NebulasFs还做为后端存储为另一个对象存储(AWS S3协议)提供服务以存储大文件。 伴随着业务的不断接入,NebulasFs也会不断完善,为业务增长提供更好的保障。 推荐阅读 分布式时序数据库QTSDB的设计与实现360大数据中心总监:如何制定可奏效的数据安全体系(360技术原创内容,转载请务必保留文末二维码,谢谢~) 关于360技术360技术是360技术团队打造的技术分享公众号,每天推送技术干货内容 更多技术信息欢迎关注“360技术”微信公众号

June 11, 2019 · 1 min · jiezi

Istio-on-ACK集成生态1-集成TSDB助力可观测性存储

阿里云容器服务Kubernetes(简称ACK)支持一键部署Istio,可以参考文档在ACK上部署使用Isito。Istio on ACK提供了丰富的监控能力,为网格中的服务收集遥测数据,其中Mixer是负责提供策略控制和遥测收集的Istio组件。使用Prometheus进行监控是Istio提供的监控能力之一。Prometheus是一个开源的监控和报警系统,Prometheus依赖少,功能齐全,广泛用于Kubernetes集群的监控系统中。Istio自0.8版本开始默认将Prometheus包含在内,Mixer支持对接到Prometheus监控设施的Adapter。用户可以通过查询service或pod看到Prometheus的运行状态和地址。也可以通过简洁明了的Prometheus的UI界面查看监测数据。 Prometheus的存储挑战及解决方案Prometheus的本地存储设计可以减少其自身运维和管理的复杂度,能够满足大部分用户监控规模的需求,但是本地存储也意味着Prometheus无法持久化数据,无法存储大量历史数据,同时也无法灵活扩展。Prometheus本身没有尝试解决以上问题,而是通过定义一组remote storage adapter标准接口,让用户可以基于这组标准接口自主决定将Promthues中的监控样本数据存储至第三方的远端存储服务中,来解决本地存储带来的问题。 TSDB for Prometheus是一种高性能,低成本,稳定可靠的在线时序数据库服务,通过内置实现的Prometheus的remote storage adapter,天然原生支持作为Promtheus的第三方在线远端存储服务。 相较于其他第三方远端存储而言,TSDB for Prometheus具有集成程度高,同时支持读写等优势。 集成程度高目前Prometheus对接第三方存储系统的主流做法是实现一个独立于第三方存储系统的remote storage adapter, 这个adapter需要单独部署和运维,另外单独部署的remote storage adapter还存在单点故障和读写性能问题。TSDB for Prometheus在服务端内置实现的Prometheus remote storage adapter,只需在Prometheus的配置文件prometheus.yaml中修改下远程读写配置,即可原生支持Prometheus直接读写TSDB,集成程度高,无需额外单独部署adapter,极大地降低了adapter的单点故障风险和运维成本。 同时支持读写当前一些第三方远端存储仅支持Prometheus将监控样本数据写入,而不支持读取。比如对于OpenTSDB、Graphite和Elasticsearch等第三方存储,Prometheus社区提供的adapter只支持写入模式,不支持读取模式。而TSDB for Prometheus同时支持读写。如要了解更多第三方存储系统对于Prometheus读写的支持程度,请参考Remote Endpoints and Storage。TSDB for Prometheus时序时空数据库(Time Series & Spatial Temporal Database,简称 TSDB)是一种高性能、低成本、稳定可靠的在线时序时空数据库服务,提供高效读写、高压缩比存储、时序数据插值及聚合计算等服务。TSDB 具备秒级写入百万级时序数据的性能,提供高压缩比低成本存储、预降采样、插值、多维聚合计算、可视化查询结果等功能。 TSDB for Prometheus是阿里云时序时空数据库TSDB为Prometheus提供的一种高性能、低成本、稳定可靠的在线远端存储服务,具备以下能力: 提供高效读写、高压缩比存储的能力,可无缝被Prometheus集成,在协议上原生支持Prometheus远端存储对接至TSDB。解决了以往需要为Prometheus额外开发remote storage adapter的问题,极大的降低了Prometheus远端存储对接TSDB的成本。TSDB for Prometheus最大程度的兼容Prometheus的PromQL查询语法,从而降低了用户的开发,迁移和维护成本。解决Prometheus local stroge 无法存储大量历史数据的场景,且无法扩展的问题。通过内置实现的Prometheus的remote storage adapter,天然原生支持作为Promtheus的第三方在线远端存储服务。相较于其他第三方远端存储而言,TSDB for Prometheus具有集成程度高,同时支持读写等优势。TSDB for Prometheus的使用要求具体可以参见使用要求 阿里云提供的不同规格的TSDB实例,设置了不同的最大写入TPS,避免过大TPS导致TSDB示例不可用,保护TSDB实例正常运行。当写入TPS超过TSDB实例允许的最大TPS时,将触发TSDB实例限流保护规则,会造成写入失败异常。因此需要根据TSDB实例规格来调整Prometheus的remote_write配置,从而实现平稳可靠的将Prometheus采集到的指标写入TSDB中。 关于Remote Write配置,除了参考Prometheus官方提供的Remote Write配置说明之外,还可以参考Prometheus对接阿里云TSDB时的写入配置最佳实践。 创建TSDB实例创建一个TSDB实例非常简单,登录TSDB 控制台,参照创建实例文档即可创建。获取开通的TSDB实例的地址,可以参考TSDB官方文档快速入门 确认Prometheus所在机器能够正常访问TSDB实例。直接使用http访问TSDB实例的地址,如果能够得到包含”Welcome to use the TSDB”的字符串,表示Prometheus所在机器能够正常访问TSDB实例。 ...

June 11, 2019 · 1 min · jiezi

使用阿里云极速型NAS构建高可用的GitLab

GitLab简介GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。Ruby on Rails 是一个可以使你开发、部署、维护 web 应用程序变得简单的框架。GitLab拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。由于Git的分布式特性,即使Gitlab不可用,开发人员仍然可以在本地提交代码。但是,某些Gitlab功能,比如CI,问题跟踪和持续集成会不可用,也会严重影响线上使用。因此高可用架构还是不可缺少的。GitLab软件架构如下图所示: GitLab高可用设计主备模式:启动2个实例,只有一个工作提供服务,数据通过分布式存储保持一致 主主模式(scales):Rails server启动多个,同时提供服务,数据库保持独立,数据通过NAS文件存储共享 GitLab高可用方案水平扩展 这种架构适用于许多Gitlab客户访问的使用场景,解决高API使用率,大量排队的Sidekiq作业的问题。 3 PostgreSQL nodes2 Redis nodes3 Consul/Sentinel nodes2 or more GitLab application nodes (Unicorn, Workhorse, Sidekiq, PGBouncer)1 NFS/Gitaly server 混合扩展 这种架构通过组件在专用节点上分离,提供高资源使各组件不会相互干扰,解决服务争用/高负载的问题。 3 PostgreSQL nodes1 PgBouncer node2 Redis nodes3 Consul/Sentinel nodes2 or more Sidekiq nodes2 or more GitLab application nodes (Unicorn, Workhorse)1 or more NFS/Gitaly servers1 Monitoring node (Prometheus, Grafana) ...

June 11, 2019 · 1 min · jiezi

如何利用边缘计算实现低延时高质量的互动课堂体验

据《2019中国在线教育行业市场前瞻分析报告》显示:未来几年,在线教育用户规模将保持15%左右的速度继续增长,到2024年预计突破4亿人,总体市场规模将突破4500亿元。 相比于传统线下,在线教育优势十分明显,它不受地域的限制,学生可利用互联网时代的碎片化时间学习,老师不用亲临现场授课,节省多方成本,同时也解决了传统优质教育资源分布不均的难题。同时,学生可以自主选择老师,同时结合大数据、人工智能、VR、AR等技术,还可实现教学风格、授课内容、学生需求的高度匹配。而相对于录播形式,在线互动课堂教学期间,师生间更可进行实时、有效的互动沟通,及时答疑,最大幅度还原学生线下学习的模式,学生的学习效果能得到有效提升。 在线互动课堂授课模式已经成为各大传统线下教育机构与在线教育创业公司的主要阵地。那么平台面临会哪些技术挑战?在这其中边缘计算又将发挥什么作用?平台又如何利用云厂商的能力,实现全面的教育在线化、数字化发展?本文将一一为您解答。 在线互动课堂的技术挑战在线互动课堂场景具有大带宽、长链路传输、广覆盖的业务特点,同时因为教学的实时性和互动性,对于网络的低延时和抗抖动能力也有较高的要求。 假设一个位于上海的老师在给遍布全国各地的学生讲课,一旦中间网络发生抖动,就会出现卡顿、音画不同步、互动延迟等问题,学生提的问题老师没有及时回答,学生的积极性也会下降,授课效果必然会大打折扣。在这背后,在线互动课堂平台主要面临以下几个技术挑战: 第一,网络延时是互动课堂的核心影响因素之一,该业务场景对网络丢包敏感,网络丢包可能直接导致用户掉线、视频卡顿、推流失败等。 第二,学生遍布各地,基于就近接入原则,平台需要在全国各主要城市部署接入服务器,理论上城市覆盖数越多,接入效果越好,用户体验提升越明显,但是这会面临高昂的成本。 第三,在暑期等业务高峰期,流量大幅增长,而传统IDC机房建设周期为3-6个月,无法及时响应平台在服务器资源、带宽资源以及专线资源方面的快速扩容需求,同时大量的资源建设在业务高峰度过之后会面临闲置,急需利用云的弹性能力来解决难题。 边缘计算为在线互动课堂带来的价值大带宽、广覆盖、强互动、低延时,在线互动课堂与边缘计算的应用场景天然契合。 首先,边缘计算可以在更靠近终端的网络边缘上提供服务,全域覆盖的节点资源,仿佛打造了一张覆盖全国的高质量、低成本的实时视频转发网络。在K12在线辅导业务场景中,空间距离的缩短可以减少复杂的长链路传输网络中,各种路由转发和网络设备处理的延时和传输时间,同时可以更好的避免网络抖动带来的掉线和卡顿问题,在互动课堂业务场景中整体低时延、强互动体验提升明显。 同时,视频类大流量业务的处理放到边缘完成,在大型公开课、名师讲堂直播等场景下会产生高并发访问,通过分布式的架构分散中心处理的压力,也能够有效避免网络拥塞,同时降低将数据传回源站的带宽成本。 之前假设的上海老师给全国学生授课的场景中,上海的老师授课媒体流会推到就近的边缘节点,在边缘节点直接进行转码,转码后的媒体流会分发到CDN边缘节点,当有用户访问时直接就近返回内容。 对于常见的跨国授课来说,阿里云边缘计算也能通过国际高速通道将海外的授课媒体流转发回国内的云中心,再通过边缘云智能选路系统以及遍布全国的边缘转发网络,将授课内容实时、高质量的呈现在学生面前。 数据显示,阿里云边缘计算可以大幅度提升传输可靠性,端到端延时降低200-300毫秒,一对一在线课程平均完课率从97%提升至99.5%,直接为平台带来业务收益。 更低成本、更灵活地启动边缘计算应用拓课云是在线教育行业音视频技术服务提供商,技术总监陈勇冀先生表示:除了实现全球高效的传输网络之外,阿里云边缘计算也为拓课云解决了灵活部署、节约成本、高效运维等问题。 他在云栖大会现场讲到:“在接入阿里云边缘节点服务(ENS)后,首先,我们能非常灵活的部署,根据当前的需求来动态的增加服务器使用的数量,启动的速度在分钟级别。后续还能根据大数据做提前预测,做到完全无人值守;其次,如果我们要把流的传输质量做到足够好,除了采用WebRTC和自研的抗丢包算法外,还有一个办法就是把服务器部署在家门口,如果按照传统方法走,我们与不同运营商去沟通,开机房、测试、接入等流程比较复杂,ENS很好的解决了这个问题,为我们省去了很多繁琐的工作;最后,这也为我们节约了很多运维成本,同时在边缘节点上部署足够多的运算能力,在机器和带宽上也得到足够的成本降低。” “边缘计算应该注重为客户提供平台能力,我们覆盖全国主流地区和运营商,并且将底层复杂的边缘设施形态封装起来,标准化地开放底层的计算/存储/网络基础能力,以及分布式所需的分发、调度、安全等能力,让客户能非常方便地搭建自己的边缘分布式业务架构,进行轻量化的运维,同时十分灵活地按需进行资源动态扩缩容。那些专业的、繁琐的、耗心力的事情交给阿里云来做,客户只需要专注于业务本身,这就是我们做边缘计算的思路。”阿里云高级技术专家王广芳表示。 不久以前,阿里云宣布全面升级ENS2.0,实现一键部署、一键升级、一键扩缩容、报警自动响应,上下游互动保障运营体系的稳健性。同时,在付费模式上做到更加灵活弹性,做到真正的轻资产运营,客户可以快速部署、按需付费、先用后付。 云、边、端一站式互动课堂解决方案在线互动课堂业务场景中,不仅需要就近的网络覆盖和实时数据传输能力,还需要视频流的处理以及视频推流、播放等端上的应用,为了让客户能够更便捷、更迅速地接入服务,阿里云提供了面向在线教育行业的一站式互动课堂解决方案。 阿里云视频云基于音视频通信RTC的覆盖全球的实时音视频传输网络,同时整合LMQ、智能存储等产品,并集成了RTC SDK、推流 SDK、播放器 SDK,实现实时音视频通话、互动直播、白板教学、实时聊天、网盘存储、文档浏览等全面的功能全面,提供高质量、一体化互动课堂解决方案。 该方案可全面覆盖在线教育业务场景,有效保障在丢包、抖动网络下的1V1、小班课互动教学体验,并通过优质直播平台,覆盖全国大班课直播,为客户提供高品质、一站式、稳定安全的互动教学体验。同时通过人工智能对1V1授课进行客观评价并对内容进行风险控制。 技术赋能,在线教育场景未来发展伴随国民教育意识的不断增强,在线教育的市场需求将不断扩大。而技术革新也会为这个看似传统的行业注入新鲜的血液。 5G时代的来临势必会助燃这个产业发展,其带来的是一场视频传输的革命,高质量视频通话使在线互动变得更加触手可及,能最大限度的还原线下教学的真实感,同时更高清晰度的互动课堂中,教师可以对学生起到更好的观察和督促作用,使学习效率和效果双重提升。 如今,人工智能已经开始赋能在线教育行业,比如通过人脸识别技术识别分析学生的微表情,及时反馈课堂表现和学习状态。再比如利用大数据和个性化推荐算法更精准地为学生匹配教学风格和知识点、利用人工智能技术为为学生批改作业、答疑解惑等等,AI的融入,可以帮助教师提升教学效率。 在线教育借助互联网技术,已经突破了线下传统教育模式的瓶颈,实现跨地域、跨时空的教育资源共享。在未来,借助于云计算、边缘计算、实时音视频通信以及直播平台、人工智能等技术,不管学生在任何地点,只要有手机或电脑,在线教育平台就可以把最优秀的老师带来他的身边。 本文作者:樰篱 原文链接 本文为云栖社区原创内容,未经允许不得转载。

June 10, 2019 · 1 min · jiezi

大型网站系统与Java中间件读书笔记上

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 这本书买了一段时间了,之前在杭州没带过去,现在读完第三章,来做做笔记 这本书前三章都在科普和回顾中间件/分布式的基础,讲得非常通俗易懂。在之前已经我写过基础分布式相关文章,大家可以先去看看: 外行人都能看懂的SpringCloud,错过了血亏!什么是ZooKeeper?什么是消息队列?什么是单点登录(SSO)一、为什么分布式?在之前的文章(外行人都能看懂的SpringCloud,错过了血亏!)也提过为什么要分布式: 模块之间独立,各做各的事,便于扩展,复用性高高吞吐量。某个任务需要一个机器运行10个小时,将该任务用10台机器的分布式跑(将这个任务拆分成10个小任务),可能2个小时就跑完了在书上给出的观点: 升级单机的处理能力的性价比越来越低,单机的处理能力存在瓶颈分布式系统更加稳定和可用(单机挂了就挂了,分布式挂了一般还有备用/不至于整个链路全挂)1.1 大型网站架构演进过程其实在没接触过分布式之前,在逛论坛的时候,经常会出现一些看起来很牛逼的词,诸如”读写分离“、”分库分表“、”主从架构“、”负载均衡“、”单点故障“等等名词,就觉得很高大上。下面我就稍微顺着”大型网站架构演进过程“来讲解一下这些词 在我们最开始接触Java项目的时候,一般来说是单机的(数据库、Web服务器都是同一台机器) 网站对外开放以后,访问量增大,服务器的压力也随之提高。此时,我们最简单的做法就是可以将数据库和应用分开,这样可以缓解一下当前系统的压力 应用服务器的压力继续增大,我们可以把应用服务器做成集群(说白了,就是加了台机器) 加了台应用服务器以后,就出现新的问题了: 用户请求的时候,走哪台服务器啊?Session是依赖单台服务器的,那Session怎么搞? 解决用户走哪台服务器,我们就在用户请求到达应用服务器之前,加了一个”负载均衡器“,这个”负载均衡器“说白了就写了用户请求会到哪台应用服务器的逻辑 比如说,一个用户请求过来,负载均衡器指派这个请求到服务器A。另一个用户请求过来,负载均衡器指派这个请求到服务器B。这样就平摊了请求— 这种方式就叫做轮询...策略还有很多种,就看你想怎么实现了,反正这个逻辑的代码放在负载均衡器上。而Session的问题,我之前写什么是单点登录(SSO)已经讲过了,一般来说我们可以将Session保存在Redis上就行了。 随着业务的发展,我们的数据量和访问量都在增长,现在有不少的业务都是读多写少的,对于这种业务也是会直接反应到数据库上。 于是,我们可以增加一个读库。写入的操作走服务器C的MySQL,读取的操作走服务器D的MySQL。这样就实现了读写分离。 一般来说,我们的写库也叫做主库,读库也叫做从库,在互联网架构中,这叫做主从架构,比如常见的架构:一主多从(详细的参考资料:如何给老婆解释什么是 Master-Slave) 针对读多写少的业务,我们还有优化策略,引入搜索引擎和缓存。 搜索引擎也相当于一个读库,使用搜索引擎的倒排表方式,能够大大提升检索的速度缓存则将热数据放入内存中,如果查询的数据在缓存中存在,则直接返回 搜索引擎和缓存的参考资料: Redis合集什么是LuceneElasticsearch入门注:这里说的索引和缓存就未必特指ES和Redis,比如缓存我也可以用本地缓存而不一定是Redis的。这里用Redis和ES只是我画图方便。 继读写分离之后,数据库还是遇到了瓶颈,此时我们就可以采用分库分表策略了: 垂直拆分— 不同的业务数据分到不同的数据库水平拆分— 将同一张表的数据拆分到不同的数据库中(原因是这张表的数据量/更新量太大了) 注:单表行数超过500万行或者单表容量超过2GB才推荐进行分库分表(如果预计三年都达不到这个数据量,不要在创建表的时候就分库分表!) —《阿里巴巴 Java开发手册》 在数据存储方面,除了关系型数据库之外,如果有别的业务场景,可能还需要引入分布式存储系统 分布式文件系统分布式Key-Value系统分布式数据库数据库问题解决之后,应用也面临着挑战(应用的功能会越做越多,应用也随之越做越大),为了不让应用持续变大,这就需要把应用拆开,从一个应用变为两个/多个应用。 不同功能/模块之间的调用不再单纯通过本机调用,引入了远程的服务调用。 某个应用只有一台机器上运行着,如果这台机器上出现了问题,导致这个应用无法运行,这就叫单点故障。 最后这本书《大型网站系统与Java中间件》的前三章主要是铺垫什么是中间件、什么是分布式(从单机演进到分布式的过程)以及讲述了网站的架构演进过程,剩下的是回顾一些基础。比如说: bio/nio/aioHTTP/SessionJVMJava多线程以及并发的基础知识JUC包下的常见类这些我都曾经多多少少都做过笔记,不妨在我的公众号下找找相关的文章。总的来说,还是读得很过瘾的!后面读完下面的章节,我会继续分享,敬请期待。 乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,关注即可获取! 觉得我的文章写得不错,点赞!

June 10, 2019 · 1 min · jiezi

阿里云DataV专业版发布为可视化创造更多可能

阿里云数据可视化应用工具DataV正式推出专业版,该版本为可视化领域专业团队和从业者量身打造,定位数据可视分析大屏搭建场景,让使用者可以轻松hold住复杂交互设计和实时数据交互查询需求。 什么是DataV?从2012年起,阿里巴巴每年的双11大促都会推出一个大屏,以多种生动的展示方式实时地显示交易情况。实时数据大屏,它的特点是各种大:屏幕大、数据量大、展示信息量大。  (2017年双11区域经济闪电图,将实时订单数据与物流干线结合展示) 作为“神屏”的幕后功臣,DataV将强大的可视化技术沉淀为模块化的、所见即所得的拖拽式搭建工具,在保持高水准视觉效果的同时,尽量降低使用门槛。而应用场景也从双 11 电商作战,扩展到智慧城市、智慧交通等诸多领域,在各行各业留下了可视化的足迹。 四大突破,DataV专业版新功能速览本次推出的DataV专业版在产品功能上有以下四大突破,可以让可视化从业人员、数据分析师、数据项目经理的工作如虎添翼。 节点式编程通过可视化、节点化的开发方式,用户可通过连线配置各类组件的动作、事件关系和参数,灵活配置气泡弹窗、数据钻取、组件联动、页面间交互、样式变更等复杂的交互效果。 (节点式编程功能介绍) 例如下图这个杭州学区查询网页App,就是通过DataV专业版来制作的,通过节点式编程功能,可以自定义点击、鼠标悬停等动作更改筛选条件,进而带动展示信息的变更。进一步配置,还能实现组件样式和效果的变更。整个页面的制作时间,从以往的天级缩短到现在的小时级,只需1个数据开发、1个设计师搭配即可轻松完成,效率也大幅提升。 (杭州学区信息查询Web App,使用DataV专业版搭建,可以支持多种交互效果) 工作空间分权能力允许用户建立多个工作空间并配置子账号,不同工作空间之间项目和权限完全隔离,不再担心多个项目并行开发时被误修改。 自定义组件开发和上传更灵活的组件二次开发,可根据需求开发自定义组件,并通过开发者工具,帮助自开发组件在DataV中更稳定运行。 (DataV开发者工具界面,该工具用户辅助用户自测组件运行是否稳定) 高级交互组件包更强大的交互分析能力,全新推出的高级交互组件,包含按钮、输入框、下拉选择器等表单组件,实现双向交互能力。 更多许多行业场景都对业务信息可视化具备很高的要求,有了DataV和数据大屏的帮助,数据可视化就能真正帮助业务人员了解全局、做出更理性的决策。 以政府行业为例,DataV能够将城市运行核心系统的各项关键数据可视化呈现,从而对包括应急指挥、城市管理、公共安全、环境保护、智能交通、基础设施等领域进行管理决策支持,赋能城市智慧管理和顺畅运行。 本文作者:云攻略小攻 原文链接 本文为云栖社区原创内容,未经允许不得转载。

June 6, 2019 · 1 min · jiezi

漫谈分布式计算框架

摘要: 本文主要谈了一些分布式计算框架方面的心得。如果问 mapreduce 和 spark 什么关系,或者说有什么共同属性,你可能会回答他们都是大数据处理引擎。如果问 spark 与 tensorflow 呢,就可能有点迷糊,这俩关注的领域不太一样啊。但是再问 spark 与 MPI 呢?这个就更远了。虽然这样问多少有些不严谨,但是它们都有共同的一部分,这就是我们今天谈论的一个话题,一个比较大的话题:分布式计算框架。 不管是 mapreduce,还是 spark 亦或 tensorflow,它们都是利用分布式的能力,运行某些计算,解决一些特定的问题。从这个 level 讲,它们都定义了一种“分布式计算模型”,即提出了一种计算的方法,通过这种计算方法,就能够解决大量数据的分布式计算问题。它们的区别在于提出的分布式计算模型不同。Mapreduce 正如其名,是一个很基本的 map-reduce 式的计算模型(好像没说一样)。Spark 定义了一套 RDD 模型,本质上是一系列的 map/reduce 组成的一个 DAG 图。Tensorflow 的计算模型也是一张图,但是 tensorflow 的图比起 spark 来,显得更“复杂”一点。你需要为图中的每个节点和边作出定义。根据这些定义,可以指导 tensorflow 如何计算这张图。Tensorflow 的这种具体化的定义使它比较适合处理特定类型的的计算,对 tensorflow 来讲就是神经网络。而 spark 的 RDD 模型使它比较适合那种没有相互关联的的数据并行任务。那么有没有一种通用的、简单的、性能还高的分布式计算模型?我觉着挺难。通用往往意味着性能不能针对具体情形作出优化。而为专门任务写的分布式任务又做不到通用,当然也做不到简单。 插一句题外话,分布式计算模型有一块伴随的内容,就是调度。虽然不怎么受关注,但这是分布式计算引擎必备的东西。mapreduce 的调度是 yarn,spark 的调度有自己内嵌的调度器,tensorflow 也一样。MPI 呢?它的调度就是几乎没有调度,一切假设集群有资源,靠 ssh 把所有任务拉起来。调度实际上应当分为资源调度器和任务调度器。前者用于向一些资源管理者申请一些硬件资源,后者用于将计算图中的任务下发到这些远程资源进行计算,其实也就是所谓的两阶段调度。近年来有一些 TensorflowOnSpark 之类的项目。这类项目的本质实际上是用 spark 的资源调度,加上 tensorflow 的计算模型。 当我们写完一个单机程序,而面临数据量上的问题的时候,一个自然的想法就是,我能不能让它运行在分布式的环境中?如果能够不加改动或稍加改动就能让它分布式化,那就太好了。当然现实是比较残酷的。通常情况下,对于一个一般性的程序,用户需要自己手动编写它的分布式版本,利用比如 MPI 之类的框架,自己控制数据的分发、汇总,自己对任务的失败做容灾(通常没有容灾)。如果要处理的目标是恰好是对一批数据进行批量化处理,那么 可以用 mapreduce 或者 spark 预定义的 api。对于这一类任务,计算框架已经帮我们把业务之外的部分(脚手架代码)做好了。同样的,如果我们的任务是训练一个神经网络,那么用 tensorflow pytorch 之类的框架就好了。这段话的意思是,如果你要处理的问题已经有了对应框架,那么拿来用就好了。但是如果没有呢?除了自己实现之外有没有什么别的办法呢? ...

June 6, 2019 · 2 min · jiezi

达摩院首席数据库科学家李飞飞云原生新战场我们如何把握先机

阿里妹导读:云计算大潮来袭,传统数据库市场正面临重新洗牌的情境,包括云数据库在内的一批新生力量崛起,动摇了传统数据库的垄断地位,而由云厂商主导的云原生数据库则将这种“改变”推向了高潮。云时代的数据库将面临怎样的变革?云原生数据库有哪些独特优势?在 DTCC 2019大会上,阿里巴巴副总裁 李飞飞博士就《下一代云原生数据库技术与趋势》进行了精彩分享。 李飞飞(花名:飞刀),阿里巴巴集团副总裁,高级研究员,达摩院首席数据库科学家,阿里云智能事业群数据库产品事业部负责人,ACM 杰出科学家。 大势所趋:云数据库市场份额增速迅猛如下图所示的是 Gartner 关于全球数据库市场份额的报告,该报告指出目前全球数据库市场份额大约为400亿美金,其中,中国数据库市场份额占比为3.7%,大约为14亿美金。 具体到数据库市场分布,传统五大数据库厂商 Oracle、Microsoft、IBM、SAP、Teradata 占比达到了80%,云数据库的份额占比接近10%,并且云数据库市场份额占比每年也在快速增长,因此, Oracle、MongoDB 等也在大力布局其在云数据库市场的竞争态势。 根据 DB-Engines 数据库市场分析显示,数据库系统正朝着多样化、多元化的方向发展,从传统的 TP 关系型数据库发展到今天的多源异构的数据库形态。目前,处于主流位置的还是大家耳熟能详的数据库系统,比如商业数据库 Oracle、SQL Server以及开源的 MySQL、PostgreSQL 等。而一些比较新的数据库系统,比如MongoDB、Redis 则开辟了一个新的赛道。数据库 License 的传统销售方式在逐渐走下坡路,而开源以及云上数据库 License 的流行程度却在不断提升。 数据库:云上应用关键的一环正如 AWS 创始人 Jeff Bezos 所说:“The real battle will be in databases”。因为云最早是从 IaaS 做起来的,从虚拟机、存储、网络,到现在如火如荼的语音识别、计算机视觉以及机器人等智能化应用,都是基于 IaaS 的,而数据库就是连接 IaaS 与智能化应用 SaaS 最为关键的一环。从数据产生、存储到消费的各个环节,数据库都至关重要。 数据库主要包括四大板块,即 OLTP、OLAP、NoSQL 以及数据库服务和管理类工具,也是云数据库厂商发力的四个方向。对于 OLTP 而言,技术发展已经历经了40年,而如今大家还在做的一件事情就是“加10元和减10元”,也就是所谓的事务处理。当数据量变得越来越大和读写冲突的原因,对数据进行在线实时分析的需求衍生出了 OLAP。由于需要 Scale out,而数据强一致性不能够得到保证,就有了NoSQL 。而最近又出现了一个新名词—— NewSQL,这是因为 NoSQL 也有所不足,故将传统 OLTP 的 ACID 保证与 NoSQL 的 Scale out 能力进行了整合,变成了NewSQL。 ...

June 6, 2019 · 2 min · jiezi

大型网站架构系列20本技术书籍推荐

分享大纲 大型网站架构系列分布式系统系列BAT技术文学系列架构设计系列本次分享总结 一、大型网站架构系列第一本:《大型网站技术架构:核心原理与案例分析》 这是本算是国内大型网站架构的经典之作,由阿里人李智慧创作,听名字就知道本书很有智慧。主要从大型网站架构的特点,架构目标(高性能,高可用,可伸缩等)基本理论讲起,并介绍了几个很有特色的案例。 之前群内分享的大型网站架构系列的基础理论大部分出自此书。 第二本:《大型网站系统与Java中间件实践》 同样出自阿里的技术牛人。此书对分布式系统的演进做了较好的介绍。对常用中间件(服务框架,数据访问层,消息中间件)做了比较深入的讲解。(原理到实践都有了) 第三本:《大型分布式网站架构设计与实践》,很抱歉本书也出自阿里系。 对面向服务的架构,分布式基础设施(缓存,持久化,消息系统,搜索引擎(lucence,solr)),互联网安全架构,系统稳定性,数据分析等做了较好的讲解。 第四本:《Web信息架构——设计大型网站》 可以较系统的建立网站信息架构设计的思想。对思考如何设计一个大型网站比较有帮助。 信息架构,注意这几个词所涉及的知识。 第五本:《高性能网站建设》,对web前端架构做了非常好的讲解。 注意此处的前端不只是 JS,CSS,HTML,是指业务逻辑层之前的部分。包括缓存,DNS等。 第六本:《实用负载均衡技术:网站性能优化攻略》,本书较详细的介绍了负载均衡,缓存代理等知识,对系统了解负载均衡技术有帮助。 第七本:《高性能电子商务平台构建:架构、设计与开发》,本书可以作为功能架构参考,因为他讲的是国内一个开源商城的架构。一方面作者可能是为了推广他的开源商城,因此建议初学者或者想了解此开源系统的人学习。不建议所有人学习。 第八本《高性能网站构建实战》,建议运维人员可以参考。里面介绍了LVS+KeepAlived实现高可用集群,高性能负载均衡器HAProxy,经久不衰的Squid,高性能缓存服务器Varnish,Ngnix等。里面有大量的安装脚本,因此建议运维或想了解如何部署的参考学习。 二、分布式系统系列 第一本:《从Paxos到Zookeeper:分布式一致性原理与实践》,这一本是Leader-us老师推荐的。对于了解分布式和Zookeeper很有帮助。内容有一致性协议,2PC,3PC,Paxos算法,Paxos的工程实践,Zookeeper的安装使用, ZooKeeper的典型应用场景等。本书也出自阿里系。 第二本:《ZeroC Ice权威指南》,作者是我们群内的S级资深架构师Leader-us老师所著。 对于学习Zeroc Ice很有帮助。Zeroc Ice是与dubbo类似的一套框架。可以实现RPC和服务治理。 关于更多ZeroC Ice知识,可以咨询Leader-us。 第三本:《Kubernetes权威指南:从Docker到Kubernetes实践全接触》是介绍Docker和Kubernetes比较不错的一本书。作者也有我们的Leader-us老师。 第四本:《大规模分布式存储系统:原理解析与架构实战》,对了解分布式存储有一定的帮助。 从单机存储到分布式存储,事务,并发控制等。对常用的分布式存储系统,键值系统,表格系统,分布式数据库等有较好介绍。理论和实践都有,如果自己没实际去思考去做,都可以归为理论。 分布式系统,大数据方面了这次就不介绍了。感兴趣的可以群内咨询。 三、BAT技术系列 推荐三本技术文学类书籍。第一本是《淘宝技术这十年》,第二本是《京东技术解密》,第三本是《华为研发》 第一本:《淘宝技术这十年》群内有电子版,个人看了至少三遍以上。生动形象的介绍了淘宝从小到大的技术发展历程。对思考技术发展有较好的帮助 第二本:《京东技术解密》,可以作为参考吧,本人买了一本,但还没详细看。总体来看,《淘宝技术这十年》质量和内容上更好一些。 第三本《华为研发》本人几年前看的是第一版,现在又第二版了。此书对华为技术的发展和管理变革有一定了解,从而指导自己对技术管理进行一些改进。 小插曲:谈一下技术和管理在个人发展中的看法。 人工作有十年了,做过几年技术也做过几年管理。在个人的经历中,对技术和管理有一些不同的看法。 首先,做几年技术后发现希望做管理,做管理后发现想做技术。经过思考发现是自己对技术和管理认识不足,知识掌握不对。 比如技术如果不能提高到架构师级别,就只能code,这样一年一年薪资不涨也基本看到了尽头。 因此做技术必须要做到架构师级别。(可能话有点慢),但是个人最近的感悟。只有做到架构级别,从一定的高度思考技术问题,才能不会被淘汰。 Leader-us<springcomingagain@qq.com> 20:18:01 专注技术,同时培养技术派的领导能力,经验越丰富,越需要在IT圈里培养知名度,参与开源或者很多技术获得 因此,我做管理后,又转到了技术。到现在基本了解如何去做一个架构师了。 到这个时候,发现应该去做管理。 呵呵~~因为个人的发展模式是技术+管理的模式发展。以下是架构,管理方面成长的知识参考。 架构方面:面向对象,设计模式,架构模式,分布式系统,业务架构(常用系统架构),具体技术广度和深度等; 管理方面:项目管理(PMP,PRINCE2),敏捷管理,流程规范(CMMI等),通用管理知识等。 四、架构设计系列 第一本:《研磨设计模式》,这本书详细对GOF设计模式进行了讲解。 设计模式讲的比较细致,透彻。传说网上有研磨设计模式作者的视频。有的可以分享一下。 这是本人推荐的详细学习设计模式的第一本书。 像HeadFirst这类的就不说了。 大话设计模式也可以看下,不过入门可以,但深入研究就需要看别的了。 第二本:前几天给大家推荐过《面向对象葵花宝典》,对理解面向对象思想有一些帮助。对面向对象理解做了较到位的描述。 第三本:《.NET应用架构设计:原则、模式与实践》,不过这本是NET写的。对常用的架构模式做了介绍。比如N层设计,业务层设计,逻辑层设计,服务层设计,数据层设计等。对了解各层的设计方法有不错的帮助。本人看这本书也至少三遍以上。 比如在服务设计中有一个幂等的模式,是分布式系统中较长用到的。 第四本:《Microsoft .NET企业级应用架构设计》,与《NET应用架构设计:原则、模式与实践》想对应的是本书也是从业务层,服务层,等进行架构模式的架构。讲解的方式有点不同。虽然是NET语言的,但是对Java或其他语言都有帮助。比如:假如一个人说MVC是设计模式,你就懂的MVC是架构模式。 第五本:最后,再给大家分享一本架构的书。原因是技术积累会成为类库,类库逐渐会变为框架。一个人架构设计的能力,很大程度体现在框架设计方面。因此,最后一本书是《架构探险:从零开始写Java Web框架》 本书从零开始,介绍了如何搭建一个web框架。bean实现,aop实现等。本书个人读了两遍,感觉对设计框架和封装模块有一定的帮助。

June 5, 2019 · 1 min · jiezi

TableStore-海量结构化数据分层存储方案

前言表格存储是阿里云自研分布式存储系统,可以用来存储海量结构化、半结构化的数据。表格存储支持高性能和容量型两种实例类型。高性能使用SSD的存储介质,针对读多写多的场景都有较好的访问延时。容量型使用的是SSD和SATA混合的存储介质。对写多的场景,性能接近高性能,读方面,如果遇到冷数据产生读SATA盘的话,延时会比高性能上涨一个量级。在海量数据存储场景下,例如时序场景,我们会希望最新的数据可以支持高性能查询,较早的数据的读写频次都会低很多。这时候一个基于表格存储高性能和容量型存储分层的需求就产生了。 方案细节表格存储近期对外正式发布的全增量一体的通道服务(参考文档),通道服务基于表格存储数据接口之上的全增量一体化服务。通道服务为用户提供了增量、全量、增量加全量三种类型的分布式数据实时消费通道。有了通道服务,我们可以很方便的构建从高性能实例下的表到容量型表之间的实时数据同步,进而可以在高性能表上使用表格存储的特性数据生命周期(参考文档),根据业务需求设置一个合理的TTL。总体来说就可以构建一个如下图所示的架构: 整个数据的流动过程如下: 业务写入端直接写入高性能实例高性能实例中的数据通过通道服务同步至容量型高性能实例中的老数据自动过期,减少存储量占用用户查询请求根据时序查询条件,判断是否是近期数据 近期数据查询进入高性能,毫秒级别返回较早数据查询进入容量型,几十毫秒后返回代码和操作流程:在高性能实例上根据业务主键需求创建数据表,并设置合理的数据TTL,然后在容量型下创建相同的schema的表用来持久化存储所有数据。 然后在通道页面创建一个全增量类型的通道: 通过控制台可以简单清晰的查看到同步的状态,并发,进度等信息: 下面贴一下通过Tunnel进行复制同样schema表TableStore表的Sample代码: func main () { //高性能实例的信息 tunnelClient := tunnel.NewTunnelClient("", "", "", "") //容量型实例的信息 client := tablestore.NewClient("", "", "", "") //配置callback到SimpleProcessFactory,配置消费端TunnelWorkerConfig workConfig := &tunnel.TunnelWorkerConfig{ ProcessorFactory: &tunnel.SimpleProcessFactory{ ProcessFunc: replicateDataFunc, CustomValue: client, }, } //使用TunnelDaemon持续消费指定tunnel daemon := tunnel.NewTunnelDaemon(tunnelClient, "", workConfig) err := daemon.Run() if err != nil { fmt.Println("failed to start tunnel daemon with error:", err) }}func replicateDataFunc(ctx *tunnel.ChannelContext, records []*tunnel.Record) error { client := ctx.CustomValue.(*tablestore.TableStoreClient) fmt.Println(client) for _, rec := range records { fmt.Println("tunnel record detail:", rec.String()) updateRowRequest := new(tablestore.UpdateRowRequest) updateRowRequest.UpdateRowChange = new(tablestore.UpdateRowChange) updateRowRequest.UpdateRowChange.TableName = "coldtable" updateRowRequest.UpdateRowChange.PrimaryKey = new(tablestore.PrimaryKey) updateRowRequest.UpdateRowChange.SetCondition(tablestore.RowExistenceExpectation_IGNORE) for _, pk := range rec.PrimaryKey.PrimaryKeys { updateRowRequest.UpdateRowChange.PrimaryKey.AddPrimaryKeyColumn(pk.ColumnName, pk.Value) } for _, col := range rec.Columns { if col.Type == tunnel.RCT_Put { updateRowRequest.UpdateRowChange.PutColumn(*col.Name, col.Value) } else if col.Type == tunnel.RCT_DeleteOneVersion { updateRowRequest.UpdateRowChange.DeleteColumnWithTimestamp(*col.Name, *col.Timestamp) } else { updateRowRequest.UpdateRowChange.DeleteColumn(*col.Name) } } _, err := client.UpdateRow(updateRowRequest) if err != nil { fmt.Println("hit error when put record to cold data", err) } } fmt.Println("a round of records consumption finished") return nil}总结通过通道服务,存储在表格存储中的结构化,半结构化数据可以实时流出,进行加工,萃取,计算或进行同步。如果是想进一步降低冷数据的存储成本,可以参考这篇文章把表格存储的数据备份到OSS归档存储。 ...

June 5, 2019 · 1 min · jiezi

PPT下载直播回放DTCC-2019阿里云数据库8大要点精彩回顾

摘要: 洞见前沿技术趋势,见证阿里云数据库成长历程。在DTCC这场数据库领域从业人士的年度盛会和交流平台上,来看看阿里云技术大牛们都带来了怎样的饕餮盛宴?8场议题的直播回顾、干货PPT下载及分享实录汇总如下2019年5月8日-5月10日,由国内知名IT技术社区主办的数据库技术交流盛会——DTCC 2019在北京新云南皇冠假日大酒店召开。数据风云,十年变迁,DTCC见证并铭记了国内数据库技术的关键成长历程。作为DTCC的老朋友和全球领先的云计算厂商,阿里云数据库团队受邀参加本次技术盛会,不仅派出了重量级嘉宾阵容,还为广大数据库业内人士和行业用户奉上了8场精彩议题。 洞见前沿技术趋势,见证阿里云数据库成长历程。在这场数据库领域从业人士难得的年度盛会和交流平台上,来看看阿里云技术大牛们都带来了怎样的饕餮盛宴。 8场议题的直播回顾、干货PPT下载及分享实录汇总如下: 1、阿里云李飞飞:云原生新战场,我们如何把握先机?直播回顾:https://yq.aliyun.com/live/1043?utm_content=g_1000061144 分享实录文字版:https://yq.aliyun.com/articles/703885?utm_content=g_1000061145 会上,阿里云POLARDB荣膺2019中国数据库年度最佳创新产品 相关阅读见:https://yq.aliyun.com/articles/702310?utm_content=g_1000061146 2、深度解码阿里数据库实现 数据库内核——基于HLC的分布式事务实现深度剖析直播回顾:https://yq.aliyun.com/live/1045?utm_content=g_1000061147 分享实录文字版:https://yq.aliyun.com/articles/703552?utm_content=g_1000061148 PPT下载:https://yq.aliyun.com/download/3566?utm_content=g_1000061149 3、海量数据毫秒级分析的背后——《阿里超大规模实时数仓架构挑战与实践解析》直播回顾:https://yq.aliyun.com/live/1047?utm_content=g_1000061150 分享实录文字版:https://yq.aliyun.com/articles/702765?utm_content=g_1000061151 PPT下载:https://yq.aliyun.com/download/3553?utm_content=g_1000061152 4、前沿技术应用知多少? 阿里云图数据库GDB带你探索互联数据的奥秘直播回顾:https://yq.aliyun.com/live/1050?utm_content=g_1000061153 分享实录文字版:https://yq.aliyun.com/articles/703444?utm_content=g_1000061154 PPT下载:https://yq.aliyun.com/download/3555?utm_content=g_1000061155 5、把握数据库发展趋势 DBA应如何避免“踩坑”?直播回顾:https://yq.aliyun.com/live/1046?utm_content=g_1000061156 分享实录文字版:https://yq.aliyun.com/articles/703521?utm_content=g_1000061157 PPT下载:https://yq.aliyun.com/download/3562?utm_content=g_1000061158 6、阿里云TSDB: 教你解锁时序时空数据库的种种黑科技直播回顾:https://yq.aliyun.com/live/1044?utm_content=g_1000061159 分享实录文字版:https://yq.aliyun.com/articles/703542?utm_content=g_1000061160 PPT下载:https://yq.aliyun.com/download/3563?utm_content=g_1000061161 7、云时代数据库迁移 & 容灾技术新进展与应用直播回顾:https://yq.aliyun.com/live/1048?utm_content=g_1000061162 分享实录文字版:https://yq.aliyun.com/articles/703544?utm_content=g_1000061163 PPT下载:https://yq.aliyun.com/download/3564?utm_content=g_1000061164 8、NoSQL数据库最新发展趋势 如何拥有居家必备的企业级能力?直播回顾:https://yq.aliyun.com/live/1049?utm_content=g_1000061165 分享实录文字版:https://yq.aliyun.com/articles/703549?utm_content=g_1000061166 PPT下载:https://yq.aliyun.com/download/3565?utm_content=g_1000061167 本文作者:七幕阅读原文 本文为云栖社区原创内容,未经允许不得转载。

June 4, 2019 · 1 min · jiezi

宜信开源分布式任务调度平台SIATASK的架构设计与运行流程

一、分布式任务调度的背景无论是互联网应用或者企业级应用,都充斥着大量的批处理任务。我们常常需要一些任务调度系统来帮助解决问题。随着微服务化架构的逐步演进,单体架构逐渐演变为分布式、微服务架构。在此背景下,很多原先的任务调度平台已经不能满足业务系统的需求,于是出现了一些基于分布式的任务调度平台。 1.1 分布式任务调度的演进在实际业务开发过程中,很多时候我们无可避免地需要使用一些定时任务来解决问题。通常我们会有多种解决方案:使用 Crontab 或 SpringCron (当然这种情况可能机器很少而且任务简单又不是很多的情况下)。然而,当应用复杂度升高、定时任务数量增多且任务之间产生依赖关系时,Crontab 进行定时任务的管理配置就会非常混乱,严重影响工作效率。这时就会产生一系列问题: 任务管理混乱,生命周期无法统一协调管理;任务之间如果存在依赖关系,难以编排。随着互联网的发展,分布式服务架构势越来越流行。相应的也需要一个分布式任务调度系统来管理分布式架构中的定时任务。 1.2 分布式任务调度架构 当垂直应用越来越多,应用之间交互也会越来越复杂,通常我们采用分布式或者微服务架构,将核心业务抽取出来,形成单独的服务。一个独立的微服务群体逐渐形成稳定的服务中心,使得业务应用能更快地响应多变的市场需求。 此时,用于提高业务复用及整合的分布式服务框架成为关键。同时,由于服务独立,一般能做到定时任务独立的情况,任务的更改对于整体系统的影响小之又小。通常我们会采用任务与调度分离的方式(如上图所示),任务的执行逻辑无需关注调度与编排,同时可以保证执行器和调度的高可用,易于开发和维护。 1.3 分布式任务调度优势在分布式服务架构的基础上,由于独立业务的数量可能很多,此时如果定时任务单独在该服务中实现,很可能会出现难以管理的情况,且避免不了由于定时任务的更改而导致的业务重启。因此,一个独立的分布式任务调度系统是很必要的,可以用来全局统筹管理所有的定时任务。同时,将任务的配置单独抽离出来,作为该分布式任务调度系统的功能,就能做到定时任务的更改不影响任何业务,也不影响整个系统: 通过调度与任务分离的方式进行管理,大大降低了开发和维护成本;分布式部署,保证了系统的高可用性、伸缩性、负载均衡,提高了容错性;可以通过控制台部署和管理定时任务,方便灵活高效;任务都可以持久化到数据库,避免了宕机和数据丢失带来的隐患,同时有完善的任务失败重做机制和详细的任务跟踪及告警策略。二、分布式任务调度技术选型2.1 分布式任务调度考虑因素 任务编排:多个业务之间的定时任务存在流程次序。任务分片:对于一个大型任务,需要分片并行执行。跨平台:除了使用 Java 技术栈(SpringBoot、Spring等)的项目之外,还有使用其他语言的应用。无侵入:业务不希望与调度高耦合,只关注业务的执行逻辑。故障转移:任务执行过程中遇到问题有补偿措施,减少人工介入。高可用:调度系统自身必须保证高可用。实时监控:实时获取任务的执行状态。可视化:任务调度的操作提供可视化页面,方便使用。动态编辑:业务的任务时钟参数可能变动,不希望停机部署。2.2 SIA-TASK与其它分布式任务调度技术比较SIA是宜信公司基础开发平台Simple is Awesome的简称,SIA-TASK(微服务任务调度平台)是其中的一项重要产品,SIA-TASK契合当前微服务架构模式,具有跨平台、可编排、高可用、无侵入、一致性、异步并行、动态扩展、实时监控等特点。 开源地址:https://github.com/siaorg/sia-task 我们先对比市场上主流的开源分布式任务调度框架,分析其优缺点,然后再介绍我们的技术选型。 Quartz: Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目。相比于 JDK 或 Spring 提供的定时任务,Quartz 对单个任务的控制基本做到了极致,以其强大功能和应用灵活性,在企业应用中发挥了巨大的作用。然而 Quartz 并不支持任务的编排(任务之间有依赖),而且不支持任务分片。TBSchedule: TBSchedule 是一个支持分布式的调度框架,能让一种批量任务或者不断变化的任务,被动态地分配到多个主机的 JVM 中,不同的线程组中并行执行。基于 ZooKeeper 的纯 Java 实现,由 Alibaba 开源。TBSchedule 侧重于任务的分发,支持任务分片,但是没有任务编排,也不是跨平台的。Elastic-Job: Elastic-Job 是当当开源的一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite 和 Elastic-Job-Cloud 组成。Elastic-Job 支持任务分片(作业分片一致性),但是没有任务编排,也不是跨平台的。Saturn: Saturn 是唯品会开源的分布式,高可用的调度服务。Saturn 在 Elastic-Job 做二次开发,支持监控、任务分片、跨平台,但是没有任务编排。Antares: Antares 是基于 Quartz 的分布式调度,支持分片、支持树形任务依赖,但不是跨平台的。Uncode-Schedule: Uncode-Schedule 是基于 Zookeeper 的分布式任务调度组件。支持所有任务在集群中不重复、不遗漏的执行。支持动态添加和删除任务。但是不支持任务分片,也没有任务编排,还不是跨平台的。XXL-JOB: XXL-JOB 是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。XXL-JOB 支持分片,简单支持任务依赖,支持子任务依赖,不是跨平台的。下面我们简单对比下 SIA-TASK 与这些任务调度框架: ...

June 4, 2019 · 2 min · jiezi

支付宝工程师如何搞定关系数据库的大脑查询优化器

摘要: 本文将深入了解OceanBase在查询优化器方面的设计思路和历经近十年时间提炼出的工程实践哲学。 前言查询优化器是关系数据库系统的核心模块,是数据库内核开发的重点和难点,也是衡量整个数据库系统成熟度的“试金石”。 查询优化理论诞生距今已有四十来年,学术界和工业界其实已经形成了一套比较完善的查询优化框架(System-R 的 Bottom-up 优化框架和 Volcano/Cascade 的 Top-down 优化框架),但围绕查询优化的核心难题始终没变——如何利用有限的系统资源尽可能为查询选择一个“好”的执行计划。 近年来,新的存储结构(如 LSM 存储结构)的出现和分布式数据库的流行进一步加大了查询优化的复杂性,本文章结合 OceanBase 数据库过去近十年时间的实践经验,与大家一起探讨查询优化在实际应用场景中的挑战和解决方案。 查询优化器简介SQL 是一种结构化查询语言,它只告诉数据库”想要什么”,但是它不会告诉数据库”如何获取”这个结果,这个"如何获取"的过程是由数据库的“大脑”查询优化器来决定的。在数据库系统中,一个查询通常会有很多种获取结果的方法,每一种获取的方法被称为一个"执行计划"。给定一个 SQL,查询优化器首先会枚举出等价的执行计划。 其次,查询优化器会根据统计信息和代价模型为每个执行计划计算一个“代价”,这里的代价通常是指执行计划的执行时间或者执行计划在执行时对系统资源(CPU + IO + NETWORK)的占用量。最后,查询优化器会在众多等价计划中选择一个"代价最小"的执行计划。下图展示了查询优化器的基本组件和执行流程。 查询优化器面临的挑战查询优化自从诞生以来一直是数据库的难点,它面临的挑战主要体现在以下三个方面: 挑战一:精准的统计信息和代价模型 统计信息和代价模型是查询优化器基础模块,它主要负责给执行计划计算代价。精准的统计信息和代价模型一直是数据库系统想要解决的难题,主要原因如下: 1、统计信息:在数据库系统中,统计信息搜集主要存在两个问题。首先,统计信息是通过采样搜集,所以必然存在采样误差。其次,统计信息搜集是有一定滞后性的,也就是说在优化一个 SQL 查询的时候,它使用的统计信息是系统前一个时刻的统计信息。 2、选择率计算和中间结果估计:选择率计算一直以来都是数据库系统的难点,学术界和工业界一直在研究能使选择率计算变得更加准确的方法,比如动态采样,多列直方图等计划,但是始终没有解决这个难题,比如连接谓词选择率的计算目前就没有很好的解决方法。 3、代价模型:目前主流的数据库系统基本都是使用静态的代价模型,比如静态的 buffer 命中率,静态的 IO RT,但是这些值都是随着系统的负载变化而变化的。如果想要一个非常精准的代价模型,就必须要使用动态的代价模型。 挑战二:海量的计划空间 复杂查询的计划空间是非常大的,在很多场景下,优化器甚至没办法枚举出所有等价的执行计划。下图展示了星型查询等价逻辑计划个数(不包含笛卡尔乘积的逻辑计划),而优化器真正的计划空间还得正交上算子物理实现,基于代价的改写和分布式计划优化。在如此海量的计划空间中,如何高效的枚举执行计划一直是查询优化器的难点。 挑战三:高效的计划管理机制 计划管理机制分成计划缓存机制和计划演进机制。 1、计划缓存机制:计划缓存根据是否参数化,优化一次/总是优化以及是否缓存可以划分成如下图所示的三种计划缓存方法。每个计划缓存方法都有各自的优缺点,不同的业务需求会选择不同的计划缓存方法。在蚂蚁/阿里很多高并发,低时延的业务场景下,就会选择参数化+优化一次+缓存的策略,那么就需要解决不同参数对应不同计划的问题(parametric query optimization),后面我们会详细讨论。 2、计划演进机制:计划演进是指对新生成计划进行验证,保证新计划不会造成性能回退。在数据库系统中, 新计划因为一些原因(比如统计信息刷新,schema版本升级)无时无刻都在才生,而优化器因为各种不精确的统计信息和代价模型始终是没办法百分百的保证新生成的计划永远都是最优的,所以就需要一个演进机制来保证新生成的计划不会造成性能回退。 OceanBase 查询优化器工程实践下面我们来看一下 OceanBase 根据自身的框架特点和业务模型如何解决查询优化器所面临的挑战。 从统计信息和代价模型的维度看,OceanBase 发明了基于 LSM-TREE 存储结构的基表访问路径选择。从计划空间的角度看,因为 OceanBase 原生就是一个分布式关系数据库系统,它必然要面临的一个问题就是分布式计划优化。从计划管理的角度看,OceanBase 有一整套完善的计划管理机制。 1.基于 LSM - TREE 的基表访问路径选择 基表访问路径选择方法是指优化器选择索引的方法,其本质是要评估每一个索引的代价并选择代价最小的索引来访问数据库中的表。对于一个索引路径,它的代价主要由两部分组成,扫描索引的代价和回表的代价(如果一个索引对于一个查询来说不需要回表,那么就没有回表的代价)。 通常来说,索引路径的代价取决于很多因素,比如扫描/回表的行数,投影的列数,谓词的个数等。为了简化我们的讨论,在下面的分析中,我们从行数这个维度来介绍这两部分的代价。 扫描索引的代价扫描索引的代价跟扫描的行数成正比,而扫描的行数则是由一部分查询的谓词来决定,这些谓词定义了索引扫描开始和结束位置。理论上来说扫描的行数越多,执行时间就会越久。扫描索引的代价是顺序 IO。 ...

May 31, 2019 · 2 min · jiezi

Schedulerx20分布式计算原理最佳实践

1. 前言Schedulerx2.0的客户端提供分布式执行、多种任务类型、统一日志等框架,用户只要依赖schedulerx-worker这个jar包,通过schedulerx2.0提供的编程模型,简单几行代码就能实现一套高可靠可运维的分布式执行引擎。 这篇文章重点是介绍基于schedulerx2.0的分布式执行引擎原理和最佳实践,相信看完这篇文章,大家都能写出高效率的分布式作业,说不定速度能提升好几倍:) 2. 可扩展的执行引擎Worker总体架构参考Yarn的架构,分为TaskMaster, Container, Processor三层: TaskMaster:类似于yarn的AppMaster,支持可扩展的分布式执行框架,进行整个jobInstance的生命周期管理、container的资源管理,同时还有failover等能力。默认实现StandaloneTaskMaster(单机执行),BroadcastTaskMaster(广播执行),MapTaskMaster(并行计算、内存网格、网格计算),MapReduceTaskMaster(并行计算、内存网格、网格计算)。Container:执行业务逻辑的容器框架,支持线程/进程/docker/actor等。Processor:业务逻辑框架,不同的processor表示不同的任务类型。以MapTaskMaster为例,大概的原理如下图所示: 3. 分布式编程模型之Map模型Schedulerx2.0提供了多种分布式编程模型,这篇文章主要介绍Map模型(之后的文章还会介绍MapReduce模型,适用更多的业务场景),简单几行代码就可以将海量数据分布式到多台机器上进行分布式跑批,非常简单易用。 针对不同的跑批场景,map模型作业还提供了并行计算、内存网格、网格计算三种执行方式: 并行计算:子任务300以下,有子任务列表。内存网格:子任务5W以下,无子任务列表,速度快。网格计算:子任务100W以下,无子任务列表。4. 并行计算原理因为并行任务具有子任务列表: 如上图,子任务列表可以看到每个子任务的状态、机器,还有重跑、查看日志等操作。 因为并行计算要做到子任务级别的可视化,并且worker挂了、重启还能支持手动重跑,就需要把task持久化到server端: 如上图所示: server触发jobInstance到某个worker,选中为master。MapTaskMaster选择某个worker执行root任务,当执行map方法时,会回调MapTaskMaster。MapTaskMaster收到map方法,会把task持久化到server端。同时,MapTaskMaster还有个pull线程,不停拉取INIT状态的task,并派发给其他worker执行。5. 网格计算原理网格计算要支持百万级别的task,如果所有任务都往server回写,server肯定扛不住,所以网格计算的存储实际上是分布式在用户自己的机器上的: 如上图所示: server触发jobInstance到某个worker,选中为master。MapTaskMaster选择某个worker执行root任务,当执行map方法时,会回调MapTaskMaster。MapTaskMaster收到map方法,会把task持久化到本地h2数据库。同时,MapTaskMaster还有个pull线程,不停拉取INIT状态的task,并派发给其他worker执行。6. 最佳实践6.1 需求 举个例子: 读取A表中status=0的数据。处理这些数据,插入B表。把A表中处理过的数据的修改status=1。数据量有4亿+,希望缩短时间。6.2 反面案例 我们先看下如下代码是否有问题? public class ScanSingleTableProcessor extends MapJobProcessor { private static int pageSize = 1000; @Override public ProcessResult process(JobContext context) { String taskName = context.getTaskName(); Object task = context.getTask(); if (WorkerConstants.MAP_TASK_ROOT_NAME.equals(taskName)) { int recordCount = queryRecordCount(); int pageAmount = recordCount / pageSize;//计算分页数量 for(int i = 0 ; i < pageAmount ; i ++) { List<Record> recordList = queryRecord(i);//根据分页查询一页数据 map(recordList, "record记录");//把子任务分发出去并行处理 } return new ProcessResult(true);//true表示执行成功,false表示失败 } else if ("record记录".equals(taskName)) { //TODO return new ProcessResult(true); } return new ProcessResult(false); }}如上面的代码所示,在root任务中,会把数据库所有记录读取出来,每一行就是一个Record,然后分发出去,分布式到不同的worker上去执行。逻辑是没有问题的,但是实际上性能非常的差。结合网格计算原理,我们把上面的代码绘制成下面这幅图: ...

May 31, 2019 · 2 min · jiezi

分布式系统关注点21构建易测试系统的六脉神剑

如果第二次看到我的文章,欢迎「文末」扫码订阅我个人的公众号(跨界架构师)哟~ 每周五早8点 按时送达。当然了,也会时不时加个餐~ 这篇是「分布式系统理论」系列的第20篇。提前预告一下,后面还有一篇文章,这个系列就结束了。 在之前,核心的概念都讲的差不多了。前面Z哥带你已经聊过了「数据一致性」、「高可用」、「易扩展」、「高性能」主题下的一些实践思路。 这篇讲怎么构建一个「易测试」的系统。 作为一位开发人员,可能一听到测试就想关掉这篇文章了。那我只能说too young,too naive。 作为关注我这个号的“跨界者“们,你不能将自己的边界划的太清楚,特别在当下这个变化越来越快、适者生存的时代。要活的像“水”一样,与所处的环境结合的更紧密。 除此之外,测试工作并不是单单测试人员的事,开发人员是不是编写了一个易测试的系统也至关重要。 在Z哥我过去的几年coding经验中,总结了六点认为有助于构建出一个易测试的系统建议,在这里分享给你。 第一点,分层。分层其实除了之前聊到的「易扩展」之外,对于测试工作的进行也是有很大帮助,规模越大的系统越是如此。 脑子里想象一下,一条业务线好比一根管道,每一次的业务操作会经历整根管道的流转最终到达终点。 往往很多时候,其实我们已经定位到了问题可能产生的范围,但是由于项目没有做好分层,导致每一次的测试工作不得不“从头开始”。这是多么痛苦的一件事。 做好分层只要记住一个概念就行,「高内聚低耦合」。具体可以参考之前的文章,文末放链接。 第二点,无状态。前面的文章里说过,满足无状态的功能点意味着可以动态的进行扩容而不用考虑“状态丢失”问题。其实同时它也支持了一种测试场景,就是「容量规划」。 为了支撑业务的不断发展以及不定期举行的大型活动,我们需要清楚的知道,到底部署多少台机器为宜。 当然,你也可以选择拍脑袋的方式进行,尽量多加一些就好了。但这不是一个科学的方法,也容易造成更多的浪费。 进行容量规划的过程就好比通过水龙头装水到一组杯子里。比如,你现在的要求是1分钟装入3L水,那么通过不断的调整杯子的数量和大小,理想情况是刚刚好达到这个要求为宜。 如果此时支持无状态,那么整个过程中水龙头一直开着就好了,你只要专心调整杯子的数量和大小就行。做好无状态具体也可以参考之前的文章,文末放链接。 第三点,避免硬编码,尽量配置化。可能你一看到那些庞杂的配置项就头疼,但是不得不说,配置对于测试工作的开展是有很大帮助的。 反而用“眼不见为净”的方式,硬编码到逻辑代码中是“掩耳盗铃”的办法。 特别是以下这些用途的变量,尽量放到配置中去,否则每次配置的变更都需要重新打包编译代码,是多么麻烦的一件事情。 容量类的配置次数类的配置开关类的配置时间类的配置这些类型的配置之间的共同点是,没有永远正确、永远合理的配置。你要根据你当前的需求,不断的调整他们。 如果可以引入一个集中式的配置中心就更好了,这样可以不用一个个登陆服务器去修改配置。 第四点,依赖注入。如果你平时经常编写单元测试的话,对这个应该感受颇深。因为支持依赖注入的代码,更容易编写单元测试。 但它的价值还不止于此,随着系统规模越来越大,对于直接在生产环境进行故障演练需求越迫切,因为这才足够真实。 但是又要求不能对正常的业务数据产生影响,怎么做?那就只能单独准备演练数据,然后写入到单独的数据库中。 这个时候,依赖注入就起作用了。我们可以将载入数据源的地方设计成支持依赖注入的,如此一来,你就可以灵活的切换到不同的数据源,进行故障演练。 public interface IDataSource{ public string getName(int id);}public class DataSourceMysql implements IDataSource{ public string getName(int id){ // 从正常的数据库里中获取数据。 }}public class DataSourceDrill implements IDataSource{public string getName(int id){ // 从故障演练的数据库里中获取数据。 }}public class UserBLL{ private IDataSource _database; public UserBLL(IDataSource database){ _database = database; } public void MethodA(int id){ // do something... var name = _database.getName(id); // do something... }}//以下是调用的时候new UserBLL(new DataSourceMysql()).MethodA(id); //处理的是正常数据new UserBLL(new DataSourceDrill()).MethodA(id); //处理的是演练数据第五点,打日志。测试工作最终做的好不好,看的是数据,是结果。这就意味着,对一个系统要求是「可观测」的。 ...

May 31, 2019 · 1 min · jiezi

ZooKeeper-学习笔记

ZooKeeper 介绍ZooKeeper(wiki,home,github) 是用于分布式应用的开源的分布式协调服务。通过暴露简单的原语,分布式应用能在之上构建更高层的服务,如同步、配置管理和组成员管理等。在设计上易于编程开发,并且数据模型使用了熟知的文件系统目录树结构 [doc ]。 共识与 Paxos在介绍 ZooKeeper 之前,有必要了解下 Paxos 和 Chubby。2006 年 Google 在 OSDI 发表关于 Bigtable 和 Chubby 的两篇会议论文,之后再在 2007 年 PODC 会议上发表了论文“Paxos Made Live”,介绍 Chubby 底层实现的共识(consensus)协议 Multi-Paxos,该协议对 Lamport 的原始 Paxos 算法做了改进,提高了运行效率 [ref ]。Chubby 作为锁服务被 Google 应用在 GFS 和 Bigtable 中。受 Chubby 的影响,来自 Yahoo 研究院的 Benjamin Reed 和 Flavio Junqueira 等人开发了被业界称为开源版的 Chubby 的 ZooKeeper(内部实现事实上稍有不同 [ref ]),底层的共识协议为 ZAB。Lamport 的 Paxos 算法出了名的难懂,如何让算法更加可理解(understandable),便成了 Stanford 博士生 Diego Ongaro 的研究课题。Diego Ongaro 在 2014 年发表了介绍 Raft 算法的论文,“In search of an understandable consensus algorithm”。Raft 是可理解版的 Paxos,很快就成为解决共识问题的流行协议之一。这些类 Paxos 协议和 Paxos 系统之间的关系,如下 [Ailijiang2016 ]: ...

May 30, 2019 · 6 min · jiezi

达摩院首席数据库科学家李飞飞云原生新战场我们如何把握先机

阿里妹导读:云计算大潮来袭,传统数据库市场正面临重新洗牌的情境,包括云数据库在内的一批新生力量崛起,动摇了传统数据库的垄断地位,而由云厂商主导的云原生数据库则将这种“改变”推向了高潮。云时代的数据库将面临怎样的变革?云原生数据库有哪些独特优势?在 DTCC 2019大会上,阿里巴巴副总裁 李飞飞博士就《下一代云原生数据库技术与趋势》进行了精彩分享。 李飞飞(花名:飞刀),阿里巴巴集团副总裁,高级研究员,达摩院首席数据库科学家,阿里云智能事业群数据库产品事业部负责人,ACM 杰出科学家。 大势所趋:云数据库市场份额增速迅猛如下图所示的是 Gartner 关于全球数据库市场份额的报告,该报告指出目前全球数据库市场份额大约为400亿美金,其中,中国数据库市场份额占比为3.7%,大约为14亿美金。 具体到数据库市场分布,传统五大数据库厂商 Oracle、Microsoft、IBM、SAP、Teradata 占比达到了80%,云数据库的份额占比接近10%,并且云数据库市场份额占比每年也在快速增长,因此, Oracle、MongoDB 等也在大力布局其在云数据库市场的竞争态势。 根据 DB-Engines 数据库市场分析显示,数据库系统正朝着多样化、多元化的方向发展,从传统的 TP 关系型数据库发展到今天的多源异构的数据库形态。目前,处于主流位置的还是大家耳熟能详的数据库系统,比如商业数据库 Oracle、SQL Server以及开源的 MySQL、PostgreSQL 等。而一些比较新的数据库系统,比如MongoDB、Redis 则开辟了一个新的赛道。数据库 License 的传统销售方式在逐渐走下坡路,而开源以及云上数据库 License 的流行程度却在不断提升。 数据库:云上应用关键的一环正如 AWS 创始人 Jeff Bezos 所说:“The real battle will be in databases”。因为云最早是从 IaaS 做起来的,从虚拟机、存储、网络,到现在如火如荼的语音识别、计算机视觉以及机器人等智能化应用,都是基于 IaaS 的,而数据库就是连接 IaaS 与智能化应用 SaaS 最为关键的一环。从数据产生、存储到消费的各个环节,数据库都至关重要。 数据库主要包括四大板块,即 OLTP、OLAP、NoSQL 以及数据库服务和管理类工具,也是云数据库厂商发力的四个方向。对于 OLTP 而言,技术发展已经历经了40年,而如今大家还在做的一件事情就是“加10元和减10元”,也就是所谓的事务处理。当数据量变得越来越大和读写冲突的原因,对数据进行在线实时分析的需求衍生出了 OLAP。由于需要 Scale out,而数据强一致性不能够得到保证,就有了NoSQL 。而最近又出现了一个新名词—— NewSQL,这是因为 NoSQL 也有所不足,故将传统 OLTP 的 ACID 保证与 NoSQL 的 Scale out 能力进行了整合,变成了NewSQL。 ...

May 29, 2019 · 2 min · jiezi

TiDB-在平安核心系统的引入及应用

作者:何志勇本文转载自公众号「平安科技数据库产品团队」。 2019 年 5 月 9 日,平安科技数据库产品资深工程师何志勇在第十届数据库技术大会 DTCC 上分享了《TiDB 在平安核心系统的引入及应用》,通过对 TiDB 进行 POC 测试,详细解析如何选择适用于金融行业级别的开源分布式数据库,以及平安“财神节”活动中引入 TiDB 的全流程应用实践案例分享。本文根据演讲内容整理。 <center>何志勇 平安科技数据库产品团队 资深工程师</center> 一、TiDB 引入的 POC 测试作为一名运维人员,引入一个新的数据库产品前必须要明确几点: 从业务的角度,引入的产品能否满足业务基本需求和使用场景。从运维管理角度看,这产品必须是可运维、可管理的,并且我们需要对其相应的功能与特性,要有一个很好的了解。产品性能稳定。所以在我们引入前从以下六个方面分别对 TiDB 进行测试验证,其中功能与架构、配置与管理、备份与恢复都是针对我们运维管理,SQL 特性、基准测试、应用场景测试则是应对业务需求和业务场景的。 1. 功能与架构TiDB 事务隔级别为 SI,支持 Spark 生态,支持动态扩容,跨数据中心部署。 这是 TiDB 官网最新的架构图: 从左至右看,可以通过 MySQL 或 MySQL 客户端接入 TiDB,TiDB 有 TiDB、PD、TiKV 三个组件,组件之间功能相互独立,需独立部署,分别负责计算、调度、存储功能;同时又相互协作,共同完成用户请求处理。在 TiKV 层各节点是使用 Raft 协议保证节点间数据的一致性,同时它还提供 Spark 接口供大数据分析。 从上往下看,可通过 Data Miaration 工具从 MySQL 迁移到 TiDB,同时提供备份恢复功能、内部性能监控监测及诊断、支持容器化部署。 TiDB 从架构及生态上基本上具备了传统数据库应有的功能。 2. SQL 特性兼容 mysql 语法,2.0 版本不支持窗口函数、分区表、视图、trigger 等。 ...

May 29, 2019 · 2 min · jiezi

分布式系统一致性协议

一致性模型本质上是进程与数据存储的约定,通过一致性模型我们可以理解和推理在分布式系统中数据复制需要考虑的问题和基本假设。那么,一致性模型的具体实现有一些呢?本文会介绍一致性协议实现的主要思想和方法。 什么是一致性协议一致性协议描述了特定一致性模型的实际实现。一致性模型就像是接口,而一致性协议就像是接口的具体实现。一致性模型提供了分布式系统中数据复制时保持一致性的约束,为了实现一致性模型的约束,需要通过一致性协议来保证。 一致性协议根据是否允许数据分歧可以分为两种: 单主协议(不允许数据分歧):整个分布式系统就像一个单体系统,所有写操作都由主节点处理并且同步给其他副本。例如主备同步、2PC、Paxos 都属于这类协议。多主协议(允许数据分歧):所有写操作可以由不同节点发起,并且同步给其他副本。例如 Gossip、POW。可以发现,它们的核心区别在于是否允许多个节点发起写操作,单主协议只允许由主节点发起写操作,因此它可以保证操作有序性,一致性更强。而多主协议允许多个节点发起写操作,因此它不能保证操作的有序性,只能做到弱一致性。 值得注意的是,一致性协议的分类方式有很多种,主要是看从哪个角度出发进行归类,常用的另一个归类方式是根据同步/异步复制来划分,这里就不多做讨论了。下面对单主协议和多主协议分别做一些共性的分析,篇幅所限,不会深入到协议细节。 单主协议单主协议的共同点在于都会用一个主节点来负责写操作,这样能够保证全局写的顺序一致性,它有另一个名字叫定序器,非常的形象。 主备复制主备复制可以说是最常用的数据复制方法,也是最基础的方法,很多其他协议都是基于它的变种。 主备复制要求所有的写操作都在主节点上进行,然后将操作的日志发送给其他副本。可以发现由于主备复制是有延迟的,所以它实现的是最终一致性。 主备复制的实现方式:主节点处理完写操作之后立即返回结果给客户端,写操作的日志异步同步给其他副本。这样的好处是性能高,客户端不需要等待数据同步,缺点是如果主节点同步数据给副本之前数据缺失了,那么这些数据就永久丢失了。MySQL 的主备同步就是典型的异步复制。 两阶段提交两阶段提交(2PC)是关系型数据库常用的保持分布式事务一致性的协议,它也属于同步复制协议,即数据都同步完成之后才返回客户端结果。可以发现 2PC 保证所有节点数据一致之后才返回给客户端,实现了顺序一致性。 2PC 把数据复制分为两步: 表决阶段:主节点将数据发送给所有副本,每个副本都要响应提交或者回滚,如果副本投票提交,那么它会将数据放到暂存区域,等待最终提交。提交阶段:主节点收到其他副本的响应,如果副本都认为可以提交,那么就发送确认提交给所有副本让它们提交更新,数据就会从暂存区域移到永久区域。只要有一个副本返回回滚就整体回滚。可以发现 2PC 是典型的 CA 系统,为了保证一致性和可用性,2PC 一旦出现网络分区或者节点不可用就会被拒绝写操作,把系统变成只读的。由于 2PC 容易出现节点宕机导致一直阻塞的情况,所以在数据复制的场景中不常用,一般多用于分布式事务中(注:实际应用过程中会有很多优化)。 分区容忍的一致性协议分区容忍的一致性协议跟所有的单主协议一样,它也是只有一个主节点负责写入(提供顺序一致性),但它跟 2PC 的区别在于它只需要保证大多数节点(一般是超过半数)达成一致就可以返回客户端结果,这样可以提高了性能,同时也能容忍网络分区(少数节点分区不会导致整个系统无法运行)。分区容忍的一致性算法保证大多数节点数据一致后才返回客户端,同样实现了顺序一致性。 下面用一个简单的示例来说明这类算法的核心思想。假设现在有一个分布式文件系统,它的文件都被复制到 3 个服务器上,我们规定:要更新一个文件,客户端必须先访问至少 2 个服务器(大多数),得到它们同意之后才能执行更新,同时每个文件都会有版本号标识;要读取文件的时候,客户端也必须要访问至少 2 个服务器获取该文件的版本号,如果所有的版本号一致,那么该版本必定是最新的版本,因为如果前面的更新操作要求必须要有大多数服务器的同意才能更新文件。 以上就是我们熟知的 Paxos、ZAB、Raft 等分区容忍的一致性协议的核心思想:一致性的保证不一定非要所有节点都保持一致,只要大多数节点更新了,对于整个分布式系统来说数据也是一致性的。上面只是一个简单的阐述,真正的算法实现是比较复杂的,这里就不展开了。 分区容忍的一致性协议如 Paxos 是典型的 CP 系统,为了保证一致性和分区容忍,在网络分区的情况下,允许大多数节点的写入,通过大多数节点的一致性实现整个系统的一致性,同时让少数节点停止服务(不能读写),放弃整体系统的可用性,也就是说客户端访问到少数节点时会失败。 值得注意的是,根据 CAP 理论,假设现在有三个节点 A、B、C,当 C 被网络分区时,有查询请求过来,此时 C 因为不能和其他节点通信,所以 C 无法对查询做出响应,也就不具备可用性。但在工程实现上,这个问题是可以被绕过的,当客户端访问 C 无法得到响应时,它可以去访问 A、B,实际上对于整个系统来说还是部分可用性的,并不是说 CP 的系统一定就失去可用性。详细的分析参考分布式系统:CAP 理论的前世今生 多主协议相比单主协议为了实现顺序一致性,不允许多个节点并发写,多主协议恰恰相反,只保证最终一致性,允许多个节点并发写,能够显著提升系统性能。由于多主协议一般提供的都是最终一致性,所以常用在对数据一致性要求不高的场景中。 Gossip 协议就是一种典型的多主协议,很多分布式系统都使用它来做数据复制,例如比特币,作为一条去中心化的公链,所有节点的数据同步都用的是 Gossip 协议。此外,Gossip 协议也在一些分布式数据库中如 Dynamo 中被用来做分布式故障检测的状态同步,当有节点故障离开集群时,其他节点可以快速检测到。 ...

May 28, 2019 · 1 min · jiezi

分布式系统关注点20阻塞与非阻塞有什么区别

如果第二次看到我的文章,欢迎「文末」扫码订阅我个人的公众号(跨界架构师)哟~ 每周五早8点 按时送达到公众号。当然了,也会时不时加个餐~前面一篇文章中,Z哥和你聊了「异步」的意义,以及如何运用它。错过这篇文章的可以先去看一下再来(分布式系统关注点——深入浅出「异步」)。 其实我知道有不少小伙伴容易将「异步」和「非阻塞」搞混。脑海里印象可能是这样的:异步=非阻塞,同步=阻塞? 其实并不是如此,Z哥我这次就想来帮你搞清楚这个问题。 同步与阻塞/非阻塞你平时编写的代码中,大部分的「同步」调用,本质上都是「阻塞」的。但是「同步」调用也可以做到「非阻塞」的效果。 还是拿我们上一篇中提到的排队买奶茶这个例子,看看为什么说是「同步」+「阻塞」。 文章里「同步」的例子说的是,你排队买奶茶,点完单继续“占着坑”,不让后面的人点单,等里面的店员做好奶茶,你拿走了后面的才能点单。这个其实就是「同步」+「阻塞」,「阻塞」体现在哪? 因为这个时候你一直“占着坑”,生怕后面的人先点单,导致店员给他先做。所以,这个时候你就死死的盯着里面,这个就是「阻塞」,因为你除了盯着其它啥都干不了。 怎么让「同步」也能不阻塞呢? 就是你虽然还是排着队“占着坑”,但是人没闲着,低头玩玩手机,时不时的问里面“我的奶茶做好了没?我的奶茶做好了没?”。这个就是「非阻塞」,因为你两次询问之间会间隔一段时间,可以在这个时候做其它的事情。本质上是通过将原本的一个「大同步」拆成多个「小同步」达到「非阻塞」的效果。 上图中,几次阻塞之间空白区域就可以用于做其它事,所以是「非阻塞」的。 异步与阻塞/非阻塞上一篇文章中的「异步」例子就是一个「非阻塞」的例子,我们来看看为什么。 奶茶店分了点单区和取餐区之后,做好的饮料就只能从取餐区拿,也意味着接待你进行点单的人并不是实际做奶茶的人。这个时候你会拿到一张取餐号,然后老老实实的去取餐区等着,而不是“占着xx不xx”。 如果你很着急要拿到奶茶,不断的问里面“我的奶茶做好了没?我的奶茶做好了没?”,那这个还是「同步」+「非阻塞」的模式。因为这个过程没有产生「回调」,是你在不断的主动发起“请求”。 但如果你不着急,就在边上开一局吃鸡,等着里面做好了叫号,到你号码了再去拿。这就是「异步」+「非阻塞」。因为这个事情是对方(里面的店员)触发完成的,这就是「回调」,是对你之前的“点单”请求进行的响应。一来一回完成一个完整的交互。 到这可能你会说,那异步不还是天然「非阻塞」的么?No、No、No。 阻塞不阻塞是你自己决定的,你可以阻塞啊。比如,你等的“回调”时候发现没带手机,玩不了吃鸡,那只能傻傻的在那等着,啥也干不了。如此,这个过程虽然还是「异步」的,但对你来说就是「阻塞」的。 工作中的同步/异步&阻塞/非阻塞「同步」+「阻塞」。这种最常见,平时写的大部分代码都是如此,就不多说了。 其实你仔细想一下就会发现,很多知名的框架,都是「同步」+「非阻塞」的,为什么呢?因为你可以继续像「同步」一样编写代码,但是可以享受到类似「异步」所能带来的更好的性能,何乐而不为? 比如大名鼎鼎的linux中的io复用模型poll/select/epoll,本质上都是「同步」+「非阻塞」的。还有知名网络通信框架Netty。 我们在设计对外的api的时候也可以使用这种模式,降低一些耗时接口调用所产生的影响。这个阮一峰老师已经写的非常清楚了,我就直接贴个链接:http://www.ruanyifeng.com/blo...。 之所以大家会有错觉,认为「异步」=「非阻塞」,其实也不是没有道理。为什么呢?因为我在脑海中搜寻来一番,的确没想到有什么知名的框架/设计是使用「异步」+「阻塞」来实现的。如果哪位小伙伴有补充,可以在评论区留言告诉大家。 「异步」+「非阻塞」就多了。任何你看到callback关键字的框架都是。 总结好了,我们一起总结一下。 这次呢,Z哥先通过同步/异步、阻塞/非阻塞之间形成的4种组合形式,聊了下它们到底是怎么回事。 然后和你聊了一下工作中哪里能看到它们的存在,以及在一些典型场景下适合用哪一种模式。 希望对你有所启发。 最后送你一个记住这4个概念的最好办法。 同步阻塞:你干吧,我看着你干同步非阻塞:你干吧,我每隔5分钟来看看异步阻塞:你干吧,好了告诉我,我等着异步非阻塞:你干吧,好了告诉我,我先去忙别的了如果还是记不住,那就记住同步/异步表示“过程”,阻塞/非阻塞表示在这个过程中的“状态”。至于这句话是怎么来的,回来看这篇文章就行。 相关文章: 分布式系统关注点——深入浅出「异步」分布式系统关注点——360°全方位解读「缓存」 作者:Zachary 出处:https://www.cnblogs.com/Zacha... 如果你喜欢这篇文章,可以点一下文末的「赞」。 这样可以给我一点反馈。: ) 谢谢你的举手之劳。 ▶关于作者:张帆(Zachary,个人微信号:Zachary-ZF)。坚持用心打磨每一篇高质量原创。欢迎扫描下方的二维码~。定期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些思考。如果你是初级程序员,想提升但不知道如何下手。又或者做程序员多年,陷入了一些瓶颈想拓宽一下视野。欢迎关注我的公众号「跨界架构师」,回复「技术」,送你一份我长期收集和整理的思维导图。 如果你是运营,面对不断变化的市场束手无策。又或者想了解主流的运营策略,以丰富自己的“仓库”。欢迎关注我的公众号「跨界架构师」,回复「运营」,送你一份我长期收集和整理的思维导图。

May 24, 2019 · 1 min · jiezi

BigData-NoSQL-ApsaraDB-HBase数据存储与分析平台概览

一、引言时间到了2019年,数据库也发展到了一个新的拐点,有三个明显的趋势: 越来越多的数据库会做云原生(CloudNative),会不断利用新的硬件及云本身的优势打造CloudNative数据库,国内以阿里云的Cloud HBase、POLARDB为代表,此块文章会有一定的引述,但不是本文的重点。NoSQL正在解决BigData领域的问题。根据Forrester NoSQL的报告,BigData NoSQL是提供 存储、计算处理、支持水平扩展、Schemaless以及灵活的数据模型,特别提到需要支持复杂计算,一般通过集成Spark或者实现单独的计算引擎实现。Cassandra商业化公司Datastax提供的产品是直接在Cassandra之上集成了Spark,另外ScyllaDB公司首页的宣传语就是The Real-Time Big Data Database。大数据的5V特性,包括 Volume:数据量大,包括采集、存储和计算的量都非常大;Variety:种类和来源多样化,包括结构化、半结构化和非结构化数据;Value:数据价值密度相对较低,或者说是浪里淘沙却又弥足珍贵;Velocity:数据增长速度快,处理速度也快,时效性要求高;Veracity:数据的准确性和可信赖度,即数据的质量需要高。5V特性可以使用BigData NoSQL数据库很好的满足,且又能满足实时的写入,分析及展现。越来越多的公司或者产品都是融合多个能力,Strapdata公司把Cassandra及ElasticSearch的能力融合在一起;Datastax直接在Cassandra之上集成了Spark;SQLServer也是融合了Spark,打造Native Spark满足DB计算能力外延的商业诉求。阿里云HBase经过公共云两年(单独的HBase在阿里内部已经发展快9年)的发展,融合开源Apache HBase、Apache Phoenix、Apache Spark、Apache Solr等开源项目,再加上一系列自研特性,满足 【一体化数据处理平台,提供一站式能力】 , 基本架构如下: 我们是站在Apache巨人的肩膀上,自研了 ApsaraDB Filesystem、HBase冷热分离、SearchIndex、SparkOnX、BDS等模块,优化了HBase、Phoenix、Spark等内核一些patch,并反馈到社区,维护打造了多模服务、数据工作台等一些列的平台能力。自研部分是我们平台核心的核心竞争力,每一层每一个组件都是我们精心打造,满足客户数据驱动业务的实际需求。为了降低客户的准入门槛,我们在Github上提供了Demo支持:aliyun-apsaradb-hbase-demo,欢迎大家关注,并贡献代码。接下来笔者会介绍各层,力求简单通俗,文中有大量的链接以衍生阅读。 二、业务视角及数据流作为一个存储计算平台,价值在满足不同的业务需求。见下图:此图描述了数据的来源、通道到沉淀到云HBase平台,再通过平台提供的Spark引擎去挖掘价值反馈给业务系统。此类似一个循环系统,在阿里内部形象称为【业务数据化,再数据业务化】。 结合架构图及业务图,此平台融合了 存储(包括实时存储及离线存储)、计算、检索等技术。整个系统都打造在ApsaraDB Filesystem统一文件层之上,把检索通过Phoenix的SearchIndex包装以降低易用性,打造领域引擎满足领域的需求,内置BDS(数据通道)实时归档数据到列存,再通过Spark引擎挖掘价值。详细参考:【选择阿里云数据库HBase版十大理由】 三、统一文件访问层ApsaraDB Filesystem(简称ADB FS)以Hadoop FileSystem API为基础构建了云HBase生态文件层底座。面向HBase生态提供了无感知的混合存储能力,极大简化了HBase生态接入云端多存储形态的复杂环境。支持OSS、阿里云HDFS、基于云盘或者本地盘构建的HDFS以及基于共享云盘构建的系统。每种分布式文件系统所用的硬件不同、成本不同、延迟不同、吞吐量不同(这里不展开)。我们可以不断扩展,只要添加一个实现xxxFileSystem即可。基于OSS直接实现的FS是无法具备原子性的元数据管理能力的,实现方案是在HDFS的namenode存元数据,实际的存储存放在OSS之上。对Rename操作只需要移动元数据,所以非常轻量。 四、HBase KV层HBase是基于Bigtable在hadoop社区的开源实现,提供了如:稀疏宽表、TTL、动态列等特性。HBase在阿里已经发展9年,已经有数位PMC及Committer,可以说在国内阿里在HBase的影响力还是数一数二的。社区也有不少的Patch也是阿里贡献。在18年,云HBase首家商业化了HBase2.0,并贡献了数十个BugFix给社区。有不少客户单独使用HBase API满足业务需求,也有不少客户使用Phoenix NewSQL层,NewSQL层提升易用性及提供了很多好用的功能。在HBase层面,除了修复社区的Bug以外,也做了几个较大的特性。在对比关系型数据方面,HBase也有天然的优势,参考:对比MySQL,一文看透HBase的能力及使用场景 冷热分离冷热分离可以降低存储成本66%左右。广泛应用于车联网、冷日志等场景下。我们把冷数据存放到OSS之上,且用户还可以使用HBase的API访问。基本原理是:把Hlog存在HDFS之上,再把冷的HFile存放在OSS之上。 GC优化GC一直是Java应用中讨论的一个热门话题,尤其在像HBase这样的大型在线存储系统中,大堆下(百GB)的GC停顿延迟产生的在线实时影响,成为内核和应用开发者的一大痛点。平台实现了CCSMap新的内存存储结构,结合offheap及新的ZenGC等一列的优化,在生产环境young GC时间从120ms减少到15ms,在实验室进一步降低到5ms左右。可以参考文章:如何降低90%Java垃圾回收时间?以阿里HBase的GC优化实践为例五、检索层HBase底层基于LSM,擅长前缀匹配和范围查找,数据模型上属于行存,大范围扫描数据对系统影响很大。我们知道,用户的需求往往是各式各样,不断变化的。对于要求高TPS,高并发,查询业务比较固定且简单的场景,HBase可以很好满足。更复杂一些,当用户对同一张表的查询条件组合有固定多个时,可以通过二级索引的方式来解决,但是二级索引有写放大问题,索引数量不能太多,一般建议不超过10个。当面对更复杂的查询模式,比如自由条件组合,模糊查询,全文查询等,用当前的索引技术是无法满足的,需要寻求新的解决方案。我们容易想到,搜索引擎,比如Lucene、Solr以及ElasticSearch,是专门面向复杂查询场景的。为了应对各种复杂的查询需求,搜索引擎运用到了大量跟LSM Tree十分不同的索引技术,比如倒排、分词、BKD Tree做数值类型索引、roaring bitmap实现联合索引、DocValues增强聚合和排序等。使用搜索引擎的技术来增强HBase的查询能力是一个十分值得深入探索的技术方向。 当前用户要想实现,复杂查询,只能重新购买新的搜索集群,通过导数据的方式将数据导入到新的搜索服务中。这种方式存在很多这样那样的问题:维护成本比较高,需要购买在线数据库,分析数据库和数据传输服务;学习门槛高,需要同时熟悉至少上诉三种服务;无法保证实时性,在线库入库和检索库入库效率不匹配;数据冗余存储,在线库索引数据和结果数据设计的所有数据都需要导入;数据一致性难保证,数据乱序问题十分常见,特别是对于分布式在线库更是如此。云HBase引入Solr,并在产品和内核上做了一系列工作,将其打造成统一的产品体验,一揽子解决了前述所有问题。用户在控制台上一键可以开通检索服务,参考文章:云HBase发布全文索引服务,轻松应对复杂查询。 检索服务的架构如上图所示,最底层是分布式文件系统的统一抽象,HBase的数据和Solr中的数据都会存储在分布式文件系统中。最上层是分布式协调服务Zookeeper,HBase、Indexer、Solr都是基于其实现分布式功能。Indexer实现了存量HBase数据的批量导入功能,有针对性地实现了数据批量导入的分布式作业机制。Indexer服务也实现了实时数据的异步同步功能,利用HBase的后台Replication机制,Indexer实现了Fake HBase功能,接收到HBase的数据后,将其转换为Solr的document,并写入solr。针对HBase写入速度比Solr快的问题,我们设计并实现了反压机制,可以将Solr中数据的延迟控制在用户设定的时间范围内,该机制同时也避免了HLog消费速度过慢的堆积问题。实时同步和批量导入可以同时运行,我们通过保序的时间戳保证了数据的最终一致性。为了提高产品的易用性,我们还基于Phoenix 实现了检索服务的SQL封装,并在存储查询等方面做了一系列优化升级,该部分在下个章节将会介绍。 六、NewSQL PhoenixPhoenix是HBase之上的SQL层,Phoenix让HBase平台从NoSQL直接进化到了NewSQL。在HBase的基础之上,再支持了Schema、Secondary Indexes、View 、Bulk Loading(离线大规模load数据)、Atomic upsert、Salted Tables、Dynamic Columns、Skip Scan等特性。目前云上最大客户有200T左右,且50%+的客户都开通了Phoenix SQL服务。我们修复了社区数十个Bug及提了不少新特性,团队也拥有1位Committer及数位contributor。在18年我们在充分测试的基础上,先于社区正式商业化了Phoenix5.0,并支持了QueryServer,支持轻量的JDBC访问。同时,社区的5.0.1也将由我们推动发布。 Phoenix本身我们做了一系列稳定性,性能等方面的优化升级,主要有:客户端优化MetaCache机制,大数据量简单查询性能提升一个数量级;索引表回查主表,使用lookupjoin的方式优化,性能提升5到7倍;轻客户端优化batch commit,性能提升2到3倍;解决Phoenix时区问题,提高易用性,降低数据一致性问题概率;禁用DESC,扫全表等有风险功能;实现大批量数据导入的Bulkload功能;等等。这些稳定性和性能方面的提升,在用户侧得到了很好的反馈。 Phoenix目前基本的架构如图所示,我们让Phoenix支持了HBase和Solr双引擎,用户可以使用SQL实现对HBase和Solr数据的管理和查询,大大提高了系统的易用性。Solr和HBase之间的同步机制可以参考上节。在支持复杂查询方面,我们设计并实现了一种新的索引:Search Index,使用方式跟Phoenix的Global Index类似,主要区别在于Search Index的索引数据存储在Solr里面,而Global Index的索引数据是一张单独的HBase表。直接通过SQL管理Search Index的生命周期、数据同步和状态,自动映射数据字段类型,并通过SQL支持复杂查询,这极大降低了用户的使用门槛。Search Index可以统一根据HBase和Solr的特性做优化,由于原表在HBase中可以通过RowKey高效查询,Solr中只需要存储作为查询条件的字段的索引数据,查询字段的原数据不需要存储在Solr中,表中的非查询字段则完全不需要存储到Solr中。相对于用户单独购买检索产品,并同步数据的方案,Search Index可以大大降低存储空间。同时,根据索引特性,Phoenix在做执行计划优化时,可以动态选择最优的索引方案。 ...

May 22, 2019 · 1 min · jiezi

离线数据处理与流数据处理的区别

离线数据处理——批处理 串行计算 流数据处理——流水线并行计算 如图所示,离线数据处理采用的是串行计算,流数据处理采用的是并行计算的方式,相比之下,流数据处理的时效性更好。 更多分布式计算入门课程:阿里云大学——开发者课堂

May 22, 2019 · 1 min · jiezi

Kafka两级调度实现分布式协调微服务任务分配Golang版

背景基于Kafka消息队列的两级协调调度架构 Kafka内部为了协调内部的consumer和kafka connector的工作实现了一个复制协议, 主要工作分为两个步骤: 通过worker(consumer或connect)获取自身的topic offset等元数据信息,交给kafka的broker完成Leader/Follower选举worker Leader节点获取到kafka存储的partation和member信息,来进行二级分配,实现结合具体业务的负载均衡分配从功能实现上两级调度,一级调度负责将Leader选举,二级调度则是worker节点完成每个成员的任务的分配 主要是学习这种架构设计思想,虽然这种方案场景非常有限 基于消息队列实现分布式协调设计 一级协调器设计:一级协调器主要是指的Coordinator部分,通过记录成员的元数据信息,来进行Leader选举,比如根据offset的大小来决定谁是Leader二级协调器设计:二级协调器主要是指的Leader任务分配部分, worker节点获取到所有的任务和节点信息,就可以根据合适的算法来进行任务的分配,最终广播到消息队列 值得我们学习的地方, 通常在kafka这种场景下,如果要针对不同的业务实现统一调度,还是蛮麻烦的, 所以比如将具体任务的分配工作从架构中迁移出去, 在broker端只负责通用层的Leader选举即可, 将具体业务的分配工作,从主业务架构分离出去,由具体业务去实现 代码实现核心设计 根据设计,我们抽象出: MemoryQueue、Worker、 Coordinator、GroupRequest、GroupResponse、Task、Assignment集合核心组件 MemoryQueue: 模拟消息队列实现消息的分发,充当kafka broker角色Worker: 任务执行和具体业务二级协调算法Coordinator: 位于消息队列内部的一个协调器,用于Leader/Follower选举 Task: 任务Assignment: Coordnator根据任务信息和节点信息构建的任务分配结果GroupRequest: 加入集群请求GroupResponse: 响应信息 MemoryQueue核心数据结构// MemoryQueue 内存消息队列type MemoryQueue struct { done chan struct{} queue chan interface{} wg sync.WaitGroup coordinator map[string]*Coordinator worker map[string]*Worker}其中coordinator用于标识每个Group组的协调器,为每个组都建立一个分配器 节点加入集群请求处理 MemoryQueue 接收事件类型,然后根据事件类型进行分发,如果是GroupRequest事件,则分发给handleGroupRequest进行处理handleGroupRequest内部先获取对应group的coordinator,然后根据当前信息buildGroupResponse发回消息队列 事件分发处理func (mq *MemoryQueue) handleEvent(event interface{}) { switch event.(type) { case GroupRequest: request := event.(GroupRequest) mq.handleGroupRequest(&request) case Task: task := event.(Task) mq.handleTask(&task) default: mq.Notify(event) } mq.wg.Done()}加入Group组请求处理 ...

May 21, 2019 · 3 min · jiezi

银行交易系统-TiDB-在线缩容迁移

作者:Dan本文转载自公众号「白噪声OG」。经历了上礼拜漫长的上线周期,终于有时间总结一下期间发生的故事。TiDB 是一款非常优秀的国产分布式 NewSQL 数据库,因其支持水平扩展性、强一致性、高可用性,从 18 年 3 月起已在国内银行的账务、支付类核心系统得到应用。 临近年中,银行重要系统的建设进入投产冲刺阶段,本次上线又有多个系统对接 TiDB,为了优化集群资源分配,引发了这次分享的主题——线上系统 TiKV 的缩容、region 的迁移,本文主要针对本次 TiKV 的缩容、迁移过程进行梳理总结。 TiDB 数据库的扩容已在官方文档进行了详细的说明(https://pingcap.com/docs-cn/op-guide/horizontal-scale/)并被各路大咖广泛提及,但缩容迁移并在银行交易系统上的实践却少有分享,这也是本文的目的之一。 进入主题,先交代下环境,服务器集群采用 NVMe+SSD 的存储方案构建了 16 个 TiKV 实例,作为重要的核心支付类系统,两地三中心五副本不可少,每个 TiKV 上 8K+ 个 region。整个迁移过程历时 5 个小时,过程中没有停止系统对外服务,很是顺滑平稳。 接下来还是看一下迁移的过程: (一) TiKV 采用 Raft 一致性算法保证副本强一致性,迁移过程本质上是扩容的逆过程,确定下线的 TiKV 打上 label 后,将 region 搬移到最终保留下来的 TiKV 上。 (二) 接下来聚焦 region 1 的 Raft Group,对其副本进行搬移,实际上所有 region 的数据是一样的,只是在保留的 TiKV 内进行 region 数据的复制,新产生的副本由于数据不完整,作为 Raft Group 中的 learner。 (三) Learner 创建后,PD 会在这样的一个 Raft Group(5 个全副本 region + 2 个 learner)中发起选举: ...

May 16, 2019 · 1 min · jiezi

借助混沌工程工具-ChaosBlade-构建高可用的分布式系统

在分布式架构环境下,服务间的依赖日益复杂,可能没有人能说清单个故障对整个系统的影响,构建一个高可用的分布式系统面临着很大挑战。在可控范围或环境下,使用 ChaosBlade 工具,对系统注入各种故障,持续提升分布式系统的容错和弹性能力,以构建高可用的分布式系统。 ChaosBlade 是什么?ChaosBlade 是一款遵循混沌工程实验原理,建立在阿里巴巴近十年故障测试和演练实践基础上,并结合了集团各业务的最佳创意和实践,提供丰富故障场景实现,帮助分布式系统提升容错性和可恢复性的混沌工程工具。点击这里,了解详情。 ChaosBlade 无需编译,下载解压即可使用,支持基础资源、Java 应用、容器服务类的混沌实验,特点是操作简洁、无侵入、扩展性强。 ChaosBlade @GitHub,点击进入 下面我们以微服务分布式系统举例,一步一步构建高可用的分布式系统。 构建高可用的分布式系统ChaosBlade 的使用方式 ChaoBlade 通过 CLI 方式调用,比如我们模拟 A 服务调用 B 提供的 com.alibaba.demo.HelloService 服务下的 hello 服务延迟 3 秒,我们可以在 B 应用上注入延迟故障,仅需两步操作:第一步:准备阶段。由于 Java 应用的故障注入是通过 Java Agent 机制实现,所以首先要先挂载 agent,执行的命令是 blade prepare jvm --process <PROCESS NAME OF B APPLICATION>第二步:执行阶段,注入故障。执行命令是 blade create dubbo delay --time 3000 --service com.alibaba.demo.HelloService --methodname hello --provider,即对 B 服务提供方提供的 com.alibaba.demo.HelloService#hello 服务注入 3 秒延迟。 ChaosBlade 使用简洁,如果想了解命令的如何使用,可在命令后面添加 -h 参数,比如 blade create dubbo delay -h。更详细的 chaosblade 操作,可详见新手指南 ...

May 14, 2019 · 2 min · jiezi

分布式数据缓存中的一致性哈希算法

一致性哈希算法在分布式缓存领域的 MemCached,负载均衡领域的 Nginx 以及各类 RPC 框架中都有广泛的应用,它主要是为了解决传统哈希函数添加哈希表槽位数后要将关键字重新映射的问题。 本文会介绍一致性哈希算法的原理及其实现,并给出其不同哈希函数实现的性能数据对比,探讨Redis 集群的数据分片实现等,文末会给出实现的具体 github 地址。 Memcached 与客户端分布式缓存Memcached 是一个高性能的分布式缓存系统,然而服务端没有分布式功能,各个服务器不会相互通信。它的分布式实现依赖于客户端的程序库,这也是 Memcached 的一大特点。比如第三方的 spymemcached 客户端就基于一致性哈希算法实现了其分布式缓存的功能。 其具体步骤如下: 向 Memcached 添加数据,首先客户端的算法根据 key 值计算出该 key 对应的服务器。服务器选定后,保存缓存数据。获取数据时,对于相同的 key ,客户端的算法可以定位到相同的服务器,从而获取数据。在这个过程中,客户端的算法首先要保证缓存的数据尽量均匀地分布在各个服务器上,其次是当个别服务器下线或者上线时,会出现数据迁移,应该尽量减少需要迁移的数据量。 客户端算法是客户端分布式缓存性能优劣的关键。 普通的哈希表算法一般都是计算出哈希值后,通过取余操作将 key 值映射到不同的服务器上,但是当服务器数量发生变化时,取余操作的除数发生变化,所有 key 所映射的服务器几乎都会改变,这对分布式缓存系统来说是不可以接收的。 一致性哈希算法能尽可能减少了服务器数量变化所导致的缓存迁移。 哈希算法首先,一致性哈希算法依赖于普通的哈希算法。大多数同学对哈希算法的理解可能都停留在 JDK 的 hashCode 函数上。其实哈希算法有很多种实现,它们在不同方面都各有优劣,针对不同的场景可以使用不同的哈希算法实现。 下面,我们会介绍一下几款比较常见的哈希算法,并且了解一下它们在分布均匀程度,哈希碰撞概率和性能等方面的优劣。 MD5 算法:全称为 Message-Digest Algorithm 5,用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一,主流编程语言普遍已有 MD5 实现。MD5 的作用是把大容量信息压缩成一种保密的格式(就是把一个任意长度的字节串变换成定长的16进制数字串)。常见的文件完整性校验就是使用 MD5。 CRC 算法:全称为 CyclicRedundancyCheck,中文名称为循环冗余校验。它是一类重要的,编码和解码方法简单,检错和纠错能力强的哈希算法,在通信领域广泛地用于实现差错控制。 MurmurHash 算法:高运算性能,低碰撞率,由 Austin Appleby 创建于 2008 年,现已应用到 Hadoop、libstdc++、nginx、libmemcached 等开源系统。Java 界中 Redis,Memcached,Cassandra,HBase,Lucene和Guava 都在使用它。 ...

May 13, 2019 · 3 min · jiezi

Whats-New-in-TiDB-300rc1

作者:段兵 2019 年 5 月 10 日,TiDB 3.0.0-rc.1 版本正式推出,该版本对系统稳定性,性能,安全性,易用性等做了较多的改进,接下来逐一介绍。 提升系统稳定性众所周知,数据库的查询计划的稳定性至关重要,此版本采用多种优化手段促进查询计划的稳定性得到进一步提升,如下: 新增 Fast Analyze 功能,使 TiDB 收集统计信息的速度有了数量级的提升,对集群资源的消耗和生产业务的影响比普通 Analyze 方式更小。新增 Incremental Analyze 功能,对于值单调增的索引能够更加方便和快速地更新其统计信息。在 CM-Sketch 中新增 TopN 的统计信息,缓解因为 CM-Sketch 哈希冲突导致估算偏大的问题,使代价估算更加准确。优化 Cost Model,利用和 RowID 列之间的相关性更加精准的估算谓词的选择率,使得索引选择更加稳定和准确。提升系统性能TableScan,IndexScan,Limit 算子,进一步提升 SQL 执行性能。TiKV 采用Iterator Key Bound Option存储结构减少内存分配及拷贝,RocksDB 的 Column Families 共享 block cache 提升 cache命中率等手段大幅提升性能。TiDB Lightning encode SQL 性能提升 50%,将数据源内容解析成 TiDB 的 types.Datum,减少 encode 过程中多余的解析工作,使得性能得到较大的提升。增强系统安全性RBAC(Role-Based Access Control)基于角色的权限访问控制是商业系统中最常见的权限管理技术之一,通过 RBAC 思想可以构建最简单”用户-角色-权限“的访问权限控制模型。RBAC 中用户与角色关联,权限与角色关联,角色与权限之间一般是多对多的关系统,用户通过成为什么样的角色获取该角色所拥有的权限,达到简化权限管理的目的,通过此版本的迭代 RBAC 功能开发完成,欢迎试用。 提升产品易用性新增 SQL 方式查询慢查询,丰富 TiDB 慢查询日志内容,如:Coprocessor 任务数,平均/最长/90% 执行/等待时间,执行/等待时间最长的 TiKV 地址,简化慢查询定位工作,提升产品易用性。新增系统配置项合法性检查,优化系统监控项等,提升产品易用性。支持对 TableReader、IndexReader 和 IndexLookupReader 算子进行内存追踪控制,对 Query 内存使用统计更加精确,可以更好地检测、处理对内存消耗较大的语句。社区贡献V3.0.0-rc.1 版本的开发过程中,开源社区贡献者给予了我们极大的支持,例如美团的同学负责开发的 SQL Plan Management 特性对于提升产品的易用性有很大的帮助,一点资讯的陈付同学与其他同学一起对 TiKV 线程池进行了重构,提高了性能并降低了延迟,掌门科技的聂殿辉同学实现 TiKV 大量 UDF 函数帮忙 TiKV 完善 Coprocessor 功能,就不再一一列举。在此对各位贡献者表示由衷的感谢。接下来我们会开展更多的专项开发活动以及一系列面向社区的培训课程,希望能对大家了解如何做分布式数据库有帮助。 ...

May 13, 2019 · 1 min · jiezi

TiDB-300rc1-Release-Notes

2019 年 5 月 10 日,TiDB 发布 3.0.0-rc.1 版,对应的 TiDB-Ansible 版本为 3.0.0-rc.1。相比 3.0.0-beta.1 版本,该版本对系统稳定性、易用性、功能、优化器、统计信息以及执行引擎做了很多改进。 TiDBSQL 优化器 利用列之间的顺序相关性提升代价估算准确度,并提供启发式参数 tidb_opt_correlation_exp_factor 用于控制在相关性无法被直接用于估算的场景下对索引扫描的偏好程度。当过滤条件中包含相关列时,在抽取复合索引的访问条件时尽可能多地匹配索引的前缀列。用动态规划决定连接的执行顺序,当参与连接的表数量不多于 tidb_opt_join_reorder_threshold 时启用。在构造 Index Join 的的内表中,以复合索引作为访问条件时,尽可能多地匹配索引的前缀列。提升对单列索引上值为 NULL 的行数估算准确度。在逻辑优化阶段消除聚合函数时特殊处理 GROUP_CONCAT ,防止产生错误的执行结果。当过滤条件为常量时,正确地将它下推到连接算子的子节点上。在逻辑优化阶段列剪裁时特殊处理一些函数,例如 RAND() ,防止产生和 MySQL 不兼容的执行结果。支持 FAST ANALYZE,通过tidb_enable_fast_analyze 变量控制。该特性通过用对 Region 进行采样取代扫描整个 region 的方式加速统计信息收集。支持 SQL PLAN MANAGEMENT。该特性通过对 SQL 进行执行计划绑定,以确保执行稳定性。该特性目前处于测试阶段,仅支持对 SELECT 语句使用绑定的执行计划,不建议在生产场景中直接使用。执行引擎 支持对 TableReader、IndexReader 和 IndexLookupReader 算子进行内存追踪控制。在慢日志中展示更多 COPROCESSOR 端执行任务相关细节。如 COPROCESSOR 任务数,平均/最长/90% 执行/等待时间,执行/等待时间最长的 TiKV 地址等。支持 PREPARE 不含占位符的 DDL 语句。Server TiDB 启动时,只允许 DDL owner 执行 bootstrap新增 tidb_skip_isolation_level_check 变量控制检查隔离级别设置为 SERIALIZABLE 时不报错在慢日志中,将隐式提交的时间与 SQL 执行时间融合在一起RBAC 权限管理 ...

May 13, 2019 · 2 min · jiezi

十五年了蚂蚁为何执着攻坚这两个技术堡垒

阿里妹导读:近日,蚂蚁金服副CTO 胡喜应邀做了《蚂蚁金服十五年技术架构演进之路》的演讲,分享蚂蚁金服对金融科技未来的判断,并首次对外公开蚂蚁金服技术人才培训体系以及 BASIC College 项目。主要观点:蚂蚁金服过去十五年,通过技术重塑了支付和微贷业务。Blockchain (区块链)、ArtificialIntelligence(人工智能)、Security(安全)、 IoT(物联网)和 Cloud computing(云计算),这五大 BASIC 技术仍会是金融科技的基石。BASIC 里最基础的能力是计算能力,只有不断提升计算能力,才能适应未来应用场景的千变万化。金融交易技术的核心是金融分布式中间件,关键是分布式数据库的能力。对数据不丢失,业务不停机是金融级高可用的极致追求,同时,更要具备主动发现风险和自我恢复的能力。金融级分布式系统,最终将走向云原生化。现有的中间件能力将通过 service mesh 形式下沉至基础设施。安全可信的执行环境是金融级系统的底线,安全容器将成为金融行业的强需求。金融级数据智能未来的趋势是 Big Data Base,我们需要开放式的计算架构,从统一存储规范,可插拔的引擎组件,融合计算引擎,到统一的智能 SQL,数据处理与人工智能系统将会进一步融合,最终形成开放智能计算架构的最佳实践。多样化的计算,如流、图、机器学习经常并存于业务场景中,蚂蚁金服联合 Berkeley 大学推进的新一代计算引擎 Ray,着力于打造一个多模,融合的金融级计算引擎,帮助业务以简单的函数式编程实现多样化的分布式计算功能。蚂蚁金服最新开源的SQLFlow,抽象出端到端从数据到模型的研发过程,配合底层的引擎及自动优化,我们希望让人工智能应用像 SQL一样简单。以下是蚂蚁金服副CTO胡喜的分享内容全文:蚂蚁金服过去十五年,通过技术重塑了支付服务小微贷款服务。我们认为 Blockchain (区块链)、Artificial intelligence(人工智能)、Security(安全)、 IoT(物联网)和 Cloud computing(云计算),这五大 BASIC 技术仍会是金融科创新发展的基石。 但是,在 BASIC 技术中最基础的能力是计算能力,只有不断提升计算能力,才能适应未来应用场景的千变万化。对蚂蚁来说,要解决两个最关键的计算问题,一个是在线交易支付的问题,另外就是解决金融级数据智能的问题,狭义来讲就是 OLTP 和 OLAP 的问题。 1、金融级云原生,让交易支付更简单讲到金融在线交易,肯定要讲到“双十一”。因为“双十一”是整个中国 IT 届技术驱动力的盛世,蚂蚁在“双十一”的发展过程当中,可以看到金融支付几乎每年都是三倍的增长,到今天,整个系统具备百万级每秒的伸缩支付能力。 背后到底怎么做的?有些技术能力就跟跳水项目的规定动作一样,一定要具备这些能力。比如怎么做分布式、微服务,消息队列的问题。具体到蚂蚁,更重要的是解决分布式事务的问题,怎么做高可用,怎么做一致性,数据不能有任何丢失,不能有任何偏差,到最后怎么能够完成金融级的分布式中间件,到现在为止,我们可以看到一点,在高可用,一致性方面我们已经做到在任何情况下的数据最终一致,保证每一笔支付扣款的资金安全。并且我们去年对整体内部的中间件进行了开源,SOFAStack 是我们这么多年沉淀在金融级的最佳实践,我们期待这些实践能够帮助到更多人,从最近开源的数据来看,有 23000 的 Star,100 多个同学来参与贡献,欢迎大家更多地去试用。 刚刚讲中间件是能够在跟数据库无关前提的情况下,能够把整个金融交易做好,这是我们基本的要求,但金融交易技术中最关键的是分布式数据库能力。2009 年,蚂蚁启动自主研发数据库 OceanBase,这是一个非常偏向于高可用,一致性分布式的数据库,通过 Paxos 算法解决内部一致性的问题,到今天为止,蚂蚁整个数据库全部跑在 OceanBase 之上。 我常常会说什么才是核心技术?有些人说,核心技术只要投入人就可以做好,其实不是这么回事,核心技术不仅仅是有人有资源,还需要时间的积累,是需要天时地利人和,还需要公司、整个业务的支持,才能发展到今天,做技术还是需要一点技术情怀,蚂蚁就是一直这样坚持下去,十年左右的时间坚持开发自己的数据库,从零开始写第一行代码,到现在为止,OceanBase 数据库集群最大处理峰值是 4200 万次 / 秒,单集群最大的节点超过 1000 台,最大存储容量超过 2PB,单表最大的行数是超过 3200 亿行,并且在少数副本故障的情况下,能够做到 RPO=0,RTO<30 秒,这个是我们对于数据库层面上所做一些努力。 ...

May 13, 2019 · 2 min · jiezi

洞见数据库前沿-集结阿里云数据库最强阵容-DTCC-2019-八大亮点抢先看

摘要: 作为DTCC的老朋友和全球领先的云计算厂商,阿里云数据库团队受邀参加本次技术盛会,不仅将派出重量级嘉宾阵容,还会为广大数据库业内人士和行业用户奉上8场精彩议题。下面小编就为大家提前梳理了8大亮点,并附上阿里云议题全集,精彩一网打尽。2019年5月8日-5月10日,由国内知名IT技术社区主办的数据库技术交流盛会——DTCC 2019将在北京新云南皇冠假日大酒店召开。数据风云,十年变迁,DTCC见证并铭记了国内数据库技术的关键成长历程。作为DTCC的老朋友和全球领先的云计算厂商,阿里云数据库团队受邀参加本次技术盛会,不仅将派出重量级嘉宾阵容,还会为广大数据库业内人士和行业用户奉上8场精彩议题,精彩不容错过。 本次DTCC大会云集多位阿里云数据库顶级大咖,将为您带来最具价值的技术交流和探讨,干货满满。由阿里巴巴集团副总裁、达摩院数据库首席科学家、阿里云智能事业群数据库产品事业部总负责 李飞飞博士领衔,Google第一代分布式SQL系统Tenzing核心人物、阿里云OLAP产品分析引擎负责人林亮,数据库内核团队资深技术专家何登成等核心团队成员将依次亮相,分别就云原生数据库、新一代自研分析型数据库、分布式数据库、时序数据库、图数据库等最in的技术话题,展开深入讨论,分享最佳实战经验。同时,李飞飞博士还将作为DTCC大会的专家顾问,把握数据技术的主题内容与方向。 洞见前沿技术趋势,见证阿里云数据库成长历程。在这场数据库领域从业人士难得的年度盛会和交流平台上,阿里云技术大牛们将带来怎样的饕餮盛宴? 下面小编就为大家提前梳理了8大亮点,并附上阿里云议题全集,精彩一网打尽。期待与您共聚一堂,共话行业未来! 温馨提示不在北京?到不了现场?没关系,我们为您准备了议题直播,欢迎点击下面的直播链接,尽情围观!5月9日-5月17日,每天下午15:00敬请锁定云栖社区直播,关注这场数据库技术干货的大咖SHOW 点击直播链接,预约观看就可领取阿里云数据库超值代金券!数量有限,先到先得哦! 亮点1:阿里云云原生数据库——我们不一样作为基础软件之一,数据库一直是企业IT系统的核心。随着云计算的到来及相关技术的不断成熟,推动了数据库行业的快速发展,传统数据库铁打的防线也正在被撕裂。 在云计算时代,云原生数据库开始崛起,通过弹性扩展、按量付费等特性获得了大量企业用户的青睐,挑战 Oracle 等传统数据库厂商的位置。在2018年,Gartner发布的数据库魔力象限中,云数据库厂商的表现极为抢眼,作为国内云计算行业的佼佼者,阿里云数据库更是跻身“远见者”象限。 为了满足弹性扩展、弹性计算、以及按需按量付费等云上应用需求,云原生数据库需要利用软硬件一体化设计,基于新兴的 RDMA、NVM 等高速硬件,研发全用户态的 IO 与网络协议栈以提供极低的延迟。 同时探索新的体系架构例如通过 shared-storage 来实现 shared-everything 和存储计算分离,提供一写多读的扩展能力。在某些高并发、对水平拓展有强需求的应用场景下,云原生数据库同时也需要探索基于 shared-nothing 的分布式架构来提供分布式数据库能力来处理分布式 SQL 查询和分布式事务处理。金融级高可用、异地多活等技术挑战也是云原生数据库所必须提供的关键能力。 演讲主题:《云时代数据库的演进》演讲嘉宾:李飞飞(花名:飞刀),阿里巴巴集团副总裁,达摩院首席数据科学家,阿里云智能事业群数据库产品事业部负责人 议题简介:阿里巴巴数据库团队自主研发的存储引擎 X-Engine 充分利用数据的冷热特性以及计算机系统结构的分层内存体系,通过冷热数据分离存储技术,提升写性能的同时降低成本。基于对以上技术挑战的不断探索和实践,阿里巴巴数据库团推出了云原生数据库 POLARDB 和其分布式版本 POLARDB-X,经受了2018年阿里巴巴双十一的交易峰值挑战并在阿里云上取得了商业化的成功。 本次分享将基于阿里云数据库近期在 VLDB,SIGMOD 上的论文内容,结合核心系统设计原理,介绍云原生数据库技术的挑战和发展趋势。 演讲时间:5月8日11:05-11:45主会场场次:主场1——数据架构 十年变迁直播时间:5月9日 15:00-16:00直播链接:https://yq.aliyun.com/live/1043?utm_content=g_1000056249亮点2:数据库内核研究,深度解码阿里数据库实现演讲主题:《POLARDB-X架构和技术演进》演讲嘉宾:何登成(花名:圭多),阿里云智能数据库产品事业部资深技术专家,DTCC的老朋友。从2005年开始一直坚守在数据库内核研发领域,先后在神州通用、网易和阿里从事数据库内核产品研发工作,目前带领团队打造阿里新一代分布式数据库POLARDB-X。 议题简介:作为阿里自研的新一代分布式数据库,POLARDB-X支撑了阿里巴巴90%以上的在线数据库应用。从AliSQL到POLARDB-X,经历了怎样的思考?在过去的一年,POLARDB-X在技术上有了哪些演进?希望能在DTCC的舞台上,跟朋友们进行深度的分享和交流。 演讲时间:5月8日16:20-17:10专场场次:数据库内核技术直播时间:5月9日 16:00-17:00直播链接:https://yq.aliyun.com/live/1045?utm_content=g_1000056250亮点3:海量数据毫秒级分析背后的架构挑战以及工程实践演讲主题:《超大规模实时数仓架构挑战与实践解析》 演讲嘉宾:林亮(花名:意博),阿里云智能数据库产品事业部研究员,曾就职Google十多年,在超大规模SQL Engine和规模存储引擎上经验丰富。目前在负责阿里云PB级分析型数据库AnalyticDB架构工作。 议题简介:数据分析领域目前正在朝着在线化方向演进,数据业务在海量数据实时写入、高并发分析、稳定性、灵活性上挑战巨大。分析型数据库AnalyticDB是阿里巴巴自主研发的超大规模PB级实时数据仓库, 近2年在上述挑战背后的技术领域稳扎稳打,做了大量的难点突破和技术创新,本次演讲深入分析AnalyticDB海量数据毫秒级分析背后的架构挑战以及工程实践。 演讲时间:5月9日09:40-10:20主会场场次:主场2——数据架构 十年变迁直播时间:5月10日 15:00-16:00直播链接:https://yq.aliyun.com/live/1047?utm_content=g_1000056251亮点4:教你解锁时序时空数据库的种种黑科技演讲主题:《阿里云TSDB: 拥抱物联网的新一代时序时空数据库》演讲嘉宾:伊翼(花名:老滚)。阿里云智能数据库产品事业部技术专家,从事TSDB核心引擎的研发工作。 议题简介:阿里云TSDB是阿里自研的一种高性能,低成本,稳定可靠的在线时序时空数据库产品。该产品统一了阿里巴巴集团90%以上的APM数据和事件型数据的存储和计算,并在广泛应用于外部的物联网,工业制造,电力,化工以及IT运维等行业。本演讲将介绍该时序时空数据库的种种黑科技:・提供千万级并发读写・双十一写入TPS达到6000万/秒・十倍以上压缩比低成本存储・PB级时序时空数据秒级聚合・每天百亿时间线的集群规模等等 演讲时间:5月8日15:50-16:30专场场次:NoSQL技术与实践直播时间:5月13日 15:00-16:00直播链接:https://yq.aliyun.com/live/1044?utm_content=g_1000056252亮点5:把握数据库发展趋势 DBA应如何避免“踩坑”?进行云时代以后,IT行业各工种的职责都在发生变化,云数据库使得日常DBA管理实现更多的自动化,大大提高日常管理效率,同时也对于企业整体投资产出可以更快获得成效。对于DBA职位的而言,当前是一个转变期,不少企业从业务开始之初就直接使用云计算。 演讲主题:《如何构建云时代DBA的知识体系》演讲嘉宾:萧少聪(花名:铁庵),阿里云智能数据库产品事业部高级产品专家,PostgreSQL中国社区常委 议题简介:如何构建云时代DBA的知识体系?通过本次演讲,希望能够协助行业中已有的DBA转型及新就业进入DBA的技术人员对云DBA加深了解,让大家在转型过程少走弯路。 云数据库 vs 传统数据库管理模式对比;云DBA知识体系构成:基础、云主机、云数据库、智能化管理;直接使用云数据库与在云主机中自建数据库的管理差异;如何成长为一名优秀的云DBA。演讲时间:5月8日11:05-11:45专场场次:云时代的数据库(上)**直播时间:5月14日15:00-16:00直播链接:https://yq.aliyun.com/live/1046?utm_content=g_1000056253亮点6:关于数据库灾备,你想知道的都在这里演讲主题:《云时代数据库迁移 & 容灾技术新进展与应用》 演讲嘉宾:付大超(花名:千震),2012年加入阿里巴巴,目前负责DTS&DBS团队和研发,在阿里云提供迁移、同步和容灾的服务,支持阿里巴巴、蚂蚁、阿里云等异地多活单元化架构,曾负责阿里全球最大的HBase集群的开发和维护工作,曾先后工作于IBM、Cisco。 议题简介:迁移&容灾是数据库的强需求,传统的迁移&容灾技术已经发展多年,随着云时代的来临,在迁移&容灾的使用场景、网络、技术都有很大的变化,如何在云时代下更简单的实现数据库的迁移&容灾,云厂商如何通过新的技术实现弯道超车,本次topic主要分享阿里云在此领域的技术新进展和应用。 演讲时间:5月9日17:10-18:00专场场次:云时代数据库(下)直播时间:5月15日15:00-16:00直播链接:https://yq.aliyun.com/live/1048?utm_content=g_1000056254亮点7:NoSQL——如何拥有居家必备的企业级能力当整个世界由IT走向DT时代,数据库领域也发生了重大变化,NoSQL已成为企业应用常态 演讲主题:《NoSQL数据库最新技术发展趋势》 演讲嘉宾:朱洁(花名:所在),阿里云智能数据库产品事业部高级产品专家,当前为阿里云数据库NoSQL数据库产品Leader。10+数据库/大数据研发管理经验,专注于数据库/大数据服务平台建设、规划和实践应用,著有畅销书《大数据架构详解:从数据获取到深度学习》。 议题简介:企业IT系统面临层出不穷的新业务,安全,成本等诸多挑战。阿里云NoSQL数据库通过与企业业务深度结合,快速创新,提供最新的技术帮助企业用户迎接挑战,获得金融、社交、直播等众多大客户的信任。 本次演讲重点介绍阿里云NoSQL数据库在全球分布式,多模,弹性,HTAP,cloudNative,图,时序,时空等众多最新领域的创新和技术实践。 演讲时间:5月10日 09:40-10:20专场场次:分布式数据库实践(下)直播时间:5月16日15:00-16:00直播链接:https://yq.aliyun.com/live/1049?utm_content=g_1000056255亮点8:前沿技术应用——图数据库知多少?数据库从业者必看演讲主题:《探索互联数据的奥秘——图数据库GDB》 演讲嘉宾:王炎(花名:夜炎),阿里云智能数据库产品事业部高级技术专家。在分布式系统、存储领域以及NoSQL系统研发领域经验丰富。18年加入阿里巴巴集团,现在阿里负责图数据库系统相关研发工作。 ...

May 8, 2019 · 1 min · jiezi

服务治理Spring-Cloud-Eureka上

服务治理:Spring Cloud Eureka(上)Netflix Eureka是由Netflix开源的一款基于REST的服务治理组件,包括Eureka Server及Eureka Client。由于种种原因,Eureka 2.x版本已经冻结开发,目前最新版本是2018年8月份发布的1.9.4版本。Spring Cloud Eureka是Pivotal公司为Netflix Eureka整合于Spring Cloud生态系统提供的版本。1. 服务发现1.1 Eureka简介Eureka是Netflix公司提供的开源服务发现组件(现已闭源),最新版本是1.9.4,该组件提供的服务发现可以为负载均衡、failover等提供支持。Eureka包括Eureka Server和Eureka Client。Eureka Server提供REST服务,Eureka Clinet多数是使用Java编写的客户端(Eureka Client可以使用其他语言编写,比如Node.js或.NET),用于简化和Eureka Server的交互。1.2 Eureka Server简单案例所有工程使用Spring Cloud的新版Greenwich.SR1和Maven构建。 1.2.1 创建Spring Cloud Eureka Server工程pom.xml内容如下: <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>watermelon.cloud</groupId> <artifactId>eureka-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-server</name> <description>Spring Cloud Eureka Server</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>Finchley版本之后,Eureka的depenecy片段稍微有点不同 ...

May 6, 2019 · 2 min · jiezi

微服务与Spring-Cloud概述

微服务与Spring Cloud随着互联网的快速发展, 云计算近十年也得到蓬勃发展, 企业的IT环境和IT架构也逐渐在发生变革,从过去的单体应用架构发展为至今广泛流行的微服务架构。 微服务是一种架构风格, 能给软件应用开发带来很大的便利,但是微服务的实施和落地会面临很大的挑战, 因此需要一套完整的微服务解决方案。 在Java领域,Spring框架的出现给Java企业级软件开发带来 了福音, 提高了开发效率。 在2014年底,Spring团队推出Spring Cloud, 目标使其成为Java 领域微服务架构落地的标准,发展至今,Spring Cloud已经成为Java领域落地微服务架构的完整解决方案, 为企业IT架构变革保驾护航。微服务架构概述1.应用架构的发展应用是可独立运行的程序代码, 提供相对完善的业务功能。 目前软件架构有三种架构类型, 分别是业务架构、应用架构、技术架构。 它们之间的关系是业务架构决定应用架构, 技术架构支撑应用架构。 架构的发展历程是从单体架构、分布式架构、SOA架构再到微服务架构。 1.1 单体架构单体架构在Java领域可以理解为一个Java Web应用程序,包含表现层、业务层、数据访问层,从controller到service再到dao,就像一条单行道,从头一路走到底,没有任何业务的拆分,开发完毕之后就是一个超级大型的War包部署。简单的单体架构示例图如下: 这种开发方式对于大型应用来说非常复杂,也有“单体地狱”的称号。我们来说说单体架构的优缺点:单体架构的优点: 易于开发:开发人员使用当前开发工具在短时间内就可以开发出单体应用。易于测试:因为不需要依赖其他接口,测试可以节约很多时间。易于部署:你只需要将目录部署在运行环境中即可。单体架构的缺点: 灵活度不够:如果程序有任何修改, 修改的不只是一个点, 而是自上而下地去修改,测试时必须等到整个程序部署完后才能看出效果。 在开发过程可能需要等待其他开发 人员开发完成后才能完成部署,降低了团队的灵活性。降低系统的性能:原本可以直接访问数据库但是现在多了一层。 即使只包含一个功能点, 也需要在各个层写上代码。系统启动慢:一个进程包含了所有业务逻辑, 涉及的启动模块过多, 导致系统的启动 时间延长。系统扩展性比较差:增加新东西的时候不能针对单个点增加, 要全局性地增加。 牵一 发而动全身。1.2 分布式架构分布式架构就是在传统的单体架构的基础上,按照业务垂直切分,每个应用都是单体架构,通过API相互调用。 分布式架构的优缺点:优点: 依赖解耦理解清晰缺点: 进程间调用的可靠性低实现技术复杂1.3 SOA架构SOA(Service-Oriented Architecture)是指面向服务的架构,面向服务的架构是一种软件体系结构, 其应用程序的不同组件通过网络上的通信协议向其他组件提供服务或消费服务,所以也是一种分布式架构。简单来说,SOA是不同业务建立不同 的服务, 服务之间的数据交互粗粒度可以通过服务接口分级, 这样松散耦合提高服务的可重用性,也让业务逻辑变得可组合, 并且每个服务可以根据使用情况做出合理的分布式部署,从而让服务变得规范,高性能,高可用。 SOA架构中有两个主要角色:服务提供者(Provider)和服务消费者(Consumer)。 阿里开源的Dubbo是SOA的典型实现。SOA架构的优缺点:优点: 把模块拆分,使用接口通信,降低模块之间的耦合度把项目拆分成若干子项目,不同团队负责不同的子项目增加功能时只需要增加一个子项目,调用其他系统的接口即可可灵活地进行分布式部署缺点: 系统之间交互需要远程通信接口开发增加工作量1.4 微服务架构微服务架构在某种程度上是SOA架构继续发展的下一步,微服务的概念最早源千Martin Flower的《Microservice》。总体来讲,微服务是一种架构风格,对于一个大型复杂的业务系统,它的业务功能可以拆分为多个相互独立的微服务,各个服务之间是松耦合的,通过各种远程协议进行同步/异步通信,各微服务均可被独立部署、扩/缩容以及服务升/降级。 2. 微服务解决方案现今微服务架构十分火爆,而采用微服务构建系统也会带来更清晰的业务划分和可扩展性。支持微服务的技术栈也是多种多样。这里主要介绍两种实现微服务的解决方案: 2.1 基于Spring Cloud的微服务解决方案基于Spring Cloud的微服务解决方案也有人称为“Spring系微服务”,Spring Cloud的技术选型是中立的,Spring Cloud框架提供微服务落地方案主要有以下三种: ...

May 5, 2019 · 1 min · jiezi

用PHP在去中心化交易所OceanOne上挂单买卖任意ERC20-token

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易! 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Benz币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if ($line == 'aw') { $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); foreach ($asset_info as $key => $asset) { echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . " ". $asset["public_key"].PHP_EOL; }}调用 getAssets API的完整输出如下: Make your choose:awrun...client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daaBenz 2b9c216c-ef60-398d-a42a-eba1b298581d 799 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9dEOS 6cfe566e-4aad-470b-8c9a-2fd35b49c68d 0CNB 965e5c6e-434c-3fa9-b780-c50f43cd955c 4.72599997 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9dBTC c6d0c728-2624-429b-8e0d-d9d19b6592fa 0 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8XIN c94ac88f-4671-3976-b60a-09064f1811e8 0.01 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d限价挂单挂限价买单 低于或者等于市场价的单.挂限价卖单 高于或者是等于市场价的单.OceanOne支持三种基类价格: USDT, XIN, BTC, 即: Benz/USDT, Benz/XIN, Benz/BTC, 这儿示范Benz/USDT. ...

May 2, 2019 · 2 min · jiezi

蚂蚁金服SOFA开源负责人鲁直不只是中间件未来会开源更多

摘要: 蚂蚁金服开源也不只是 SOFA 中间件框架,未来会开源更多的东西,包括 AI 方面的一些技术,也希望整个社区能够多关注蚂蚁金服在开源上面未来的举措。本文转载自微信公众号:Linux中国,原作者:王兴宇 近日,技术媒体Linux中国的创始人王兴宇对蚂蚁金服SOFA开源负责人鲁直,就SOFA 5、ServiceMesh、Serverless、Seata等技术内容进行了探讨,以下为专访文章。 虽然我和鲁直在微信上已经联系很久了,但这还是第一次见面。交谈中,我了解到鲁直是2009 年加入阿里巴巴工作,已经有十年了。刚开始是在1688.COM 做业务系统,对中间件技术非常感兴趣,也会经常研究各种中间件的实现和功能。后来在 2013年时,为了更深入地学习研究中间件框架,转到了蚂蚁金服中间件团队,从那个时候开始就一直在做 SOFA。 目前鲁直在SOFA的团队主要负责的工作包括几个部分。其中一个主要部分就是 SOFA 开源相关的工作。SOFA 的产品体系非常广,包括已经对外开源的部分、内部整个微服务体系,以及 SOFA 框架等等——而这些开源相关的工作主要是由鲁直负责推动的。 当然,作为技术负责人,鲁直既要带技术团队也要做技术工作。谈及这一点,鲁直说: “我觉得做技术管理,跟普通的管理不太一样,因为技术管理最重要的一个点是除了管理之外,还要保持一定的技术判断力和敏锐度。对一些新技术,包括团队中遇到一些重大的技术问题,你都要有一些方向性的判断。虽然最后不一定是你具体解决的,但是在整个团队的技术攻坚和技术选型上,要一起确立方向。” 我以前也做过十余年的技术管理,我很能够感受这种情况,重大问题技术负责人更要迎难而上。 SOFA 5 落子 Service Mesh就我了解的情况,现在 SOFA 已经发展到了 SOFA5 了。在 SOFA4阶段,主要的任务是将开源体系捋清楚了,然后开始按步骤地开源;到现在发展到了 SOFA5。我想知道从 SOFA4 发展到 SOFA5,是什么让蚂蚁金服中间件团队判断 SOFA4 的阶段性目标已经达成,可以迈进到新的 SOFA5 阶段了呢? “从整个业界趋势上来讲,SOFA4 的架构相对来说还是偏传统一些,更多是对我们之前的技术框架的整理和梳理。在这个阶段,SOFA 的代码经过了非常多的优化和重构,才达到了对外开源的要求,从而 SOFA 走上了开源核心的模式,逐步分阶段的将各个部分进行了开源。”鲁直讲到,“但是,从我们对业界的整体判断上来说,未来无疑是云的时代,所以说要考虑怎么让所有的业务系统能够提供云的能力,比如说 Serverless。” 接着这个话题,鲁直讲了他对云计算的理解:“一方面云计算肯定要为整个业务的发展提供更加方便的基础资源,可以不用去关心底层的基础设施。Serverless字面的意思就是说‘无服务器’——我不用关心服务器怎么来的,不用关心基础设施,只要关心业务代码就可以了。那反过来对于云服务商来说,经过了这一层抽象,其资源利用率会更高,可以有更多的利润空间,这是一个双赢的局面。对于用户来讲,这种好处是实实在在的,可以更少关注基础设施,只关心代码就可以了。” “我们希望在 SOFA5 的方向上,在这个新的迭代中,去让业务——包括让未来我们开源出来各种功能、各样服务模式——都更多地去关心自己的业务代码,而不用再过多地关心基础设施。”鲁直说, 在 SOFA5 中,一个重要的方向就是 Service Mesh这个方向,这将是 SOFA5 中非常重要的特性。鲁直强调了其对 Service Mesh 技术的看好:“我认为 Service Mesh 是迈向未来往前走的非常关键的一步,让业务不用再关心基础设施。通过 Service Mesh,我们可以将很多技术能力直接放到基础设施里面,而业务可以不用感知到这一层。原来可能需要花几个小时或者更多的时间解决的基础设施问题,现在可以通过 Service Mesh解决掉。” ...

April 30, 2019 · 2 min · jiezi

分布式系统CAP-理论的前世今生

CAP 理论是分布式系统设计中的一个重要理论,虽然它为系统设计提供了非常有用的依据,但是也带来了很多误解。本文将从 CAP 诞生的背景说起,然后对理论进行解释,最后对 CAP 在当前背景下的一些新理解进行分析,澄清一些对 CAP 的误解。 CAP 理论诞生的背景CAP 理论的是在“数据一致性 VS 可用性”的争论中产生。CAP 的作者 Brewer 在 90 年代的时候就开始研究基于集群的跨区域系统(实质上是早期的云计算),对于这类系统而言,系统可用性是首要目标,因此他们采用了缓存或者事后更新的方式来优化系统的可用性。尽管这些方法提升了系统的可用性,但是牺牲了系统数据一致性。 Brewer 在 90 年代提出了 BASE 理论(基本可用、软状态、最终一致性),这在当时还不怎么被接受。因为大家还是比较看重 ACID 的优点,不愿意放弃强一致性。因此,Brewer 提出了 CAP 理论,目的就是为了开阔分布式系统的设计空间,通过“三选二”的公式,解放思想,不要只抓着一致性不放。 理解了 CAP 诞生的背景,我们才能更加深入的理解 CAP 理论,以及它带来的启示。“三选二”的观点虽然帮助大家开拓了设计思路,但是也带来了很多误解。下面我们会逐一分析,首先来看一下 CAP 理论的解释。 CAP 理论的经典解释CAP 定理是分布式系统设计中最基础,也是最为关键的理论。它指出,分布式数据存储不可能同时满足以下三个条件。 一致性(Consistency):每次读取要么获得最近写入的数据,要么获得一个错误。可用性(Availability):每次请求都能获得一个(非错误)响应,但不保证返回的是最新写入的数据。分区容忍(Partition tolerance):尽管任意数量的消息被节点间的网络丢失(或延迟),系统仍继续运行。CAP 定理表明,在存在网络分区的情况下,一致性和可用性必须二选一。当网络发生分区(不同节点之间的网络发生故障或者延迟较大)时,要么失去一致性(允许不同分区的数据写入),要么失去可用性(识别到网络分区时停止服务)。而在没有发生网络故障时,即分布式系统正常运行时,一致性和可用性是可以同时被满足的。这里需要注意的是,CAP 定理中的一致性与 ACID 数据库事务中的一致性截然不同。ACID 的 C 指的是事务不能破坏任何数据库规则,如键的唯一性。与之相比,CAP 的 C 仅指单一副本这个意义上的一致性,因此只是 ACID 一致性约束的一个严格的子集。 CAP 理论看起来难理解,其实只要抓住一个核心点就能推导出来,不用死记硬背。在出现网络分区的时候, 如果系统不允许写入,那么意味着降低了系统的可用性,但不同分区的数据能够保持一致,即选择了一致性。如果系统允许写入,那么意味着不同分区之间的数据产生不一致,系统可用性得到保障,即选择可用性。CAP 的新理解CAP 经常被误解,很大程度上是因为在讨论 CAP 的时候可用性和一致性的作用范围往往都是含糊不清的。如果不先定义好可用性、一致性、分区容忍在具体场景下的概念,CAP 实际上反而会束缚系统设计的思路。首先,由于分区很少发生,那么在系统不存在分区的情况下没什么理由牺牲 C 或 A。其次,C 与 A 之间的取舍可以在同一系统内以非常细小的粒度反复发生,而每一次的决策可能因为具体的操作,乃至因为牵涉到特定的数据或用户而有所不同。最后,这三种性质都可以在程度上都可以进行度量,并不是非黑即白的有或无。可用性显然是在 0% 到 100% 之间连续变化的,一致性分很多级别,连分区也可以细分为不同含义,如系统内的不同部分对于是否存在分区可以有不一样的认知。 ...

April 29, 2019 · 1 min · jiezi

共识问题

共识:一致同意,完整(只决定一次),有效,终止(宕机不回来)。要多数都同意,很慢。paxos完全符合,单raft,zap考虑的是宕机还会回来的情况,用日志保证。能解决诸如以下问题: 全序广播相当于重复多伦共识:但raft和zap等直接实现全序广播内有一次一值的共识。单领导者选取:1选出一位领导者,2对领导者的提议进行表决(防止1,一个节点相信自己是领导)投票是同步的,动态成员扩展难,依靠超时检测节点失效,若只有一条特定网络不可靠,会进入领导频繁二人转局面共识算法raft数据一致性是通过日志复制的方式,client发给leader(写只发给leader,follower备份恢复用),leader写入日志,同步给follower,当多数follower写入日志并返回给leader时,leader提交数据,返回给客户端确认消息, 发给follower数据已提交,follower提交数据,发回确认给leader。所有的发送都随着调频发过去。raft中所有server之间的通信都是RPC调用,并且只有两种类型的RPC调用:第一种是RequestVote,用于选举leader;第二种是AppendEntries。日志和投票结果都需要持续化写在磁盘中,保证宕机后重启任然正常。 leader(有任期字段term),candidate, follower.每个节点有在T到2T之间随机选择超时时间。leader和follower通过跳频联系。当一个follower收不到leader的跳频超时时将发起投自己的票。任何一个follower只能投一票。当一轮投票结束有多个候选者时,这几个候选者重新分配随机的超时时间。 当确认提交后,leader会一直不断地重试提交的rpc给follower、重试,直到请求成功;即使follower宕机了,重启后leader仍会接着发请求,直到请求成功,当leader宕机,如何向follower继续发;1.leader的日志只能增加,=》所以在选择时选term大,log长的 2.leader会把自己的log复制到其他机器,如果新达到多数并且此任期已有数据过半(挂前的一次数据不会被重复提交)就提交,只提交新任期的,同步还是要同步。为了恢复log一致性,leader为集群中所有follower都保存一个状态变量,即nextIndex:1)nextIndex是leader准备向某个follower发送的下一个log entry的index;2)当leader刚刚即位后,nextIndex的初始值是(1+leader's last index);当leader看到请求被拒绝时,其动作非常简单:只需将nextIndex-1,再次尝试。 term需要存盘任意一个server在一个term内只能投出一票;一旦已经投给了一个candidate,它必须拒绝其他candidate的投票请求;其实server根本不在意把票投给谁,它只会把票投给最先到请求到它的candidate;为了保证这一点,必须把投票信息持久保存到磁盘上,这样可以保证即使该server投完票后宕机,稍后又立即重启了,也不会在同一个term内给第二个candidate投票了。每个日志entry:iterm+index.每次发送AppendEntries时需要带上一次的,检查是否一样,一样才接受来保证所有机器log一致, paxosbasic paxos 这里有个错误。第二阶段若N>=ResN,接受提案,若N<ResN不接受。实际上这里的proposal是leader。共识算法正常是proposor,leader,accepter,leaner(先忽略),用来决议proposer的提议号和是否成功的。每次proposal先到leader(可随机选取,不重要),leader发给accepter若没有冲突返回any否则返回已选的,继续上述过程。 问题:多个Proposal可能出现死锁一直循环递增N的情况: 上面这个是https://www.microsoft.com/en-... 为了方便理解,去除了实现细节。实时上再应用中,客户端不会自己处理冲突+1再次投票和发送给其他leaner,这些应该由另一个角色,在basic中,由一群c协调者,可以和acceptor一样,或者是其中的部分构成,每轮随机一个c作为leader,负责收集本轮结果和通知leaner。proposal->leader(每个client随机发就可以作为本轮leader)->pre->acceptors返回最大N的值V->带N请求->acceptors->leader->返回给proposal->client失败或者成功或再次投票->投票成功后发给leaner。此过程中CLIENT2再次发送是另一个leader。 fast paxos 若proposal和acceptor,leader,leaner都是分布式,且要持久化,持久化+发送来回的代价就多了,若leader发现没有冲突,不再参与,proposal直接提交给acceptor(同一轮只投给先到的),直接发送给leaner,可以理解为基于乐观锁的思想,leaner和CLIENT都自行决议, 若proposal没有决策成功(先到的就是投票,没有半数以上的),1.重新引入leader,异步发送给协调者,协调者选择(因为acceptor只投一次),发给proposal结果。(再次引入leader)2.无leader,在acceptor决议后发送给所有acceptor,其他acceptor收到此消息后对i+1轮的可以比较投票(即使同时刻一个一半也可以再比较投一次)。https://www.microsoft.com/en-...muti-paxos 当leader稳定,可以省去prepare阶段 具体做法如下: ① 当某个副本节点通过选举成为Master后,就会使用新分配的编号N来广播一个Prepare消息,该Prepare消息会被所有未达成一致的Instance和目前还未开始的Instance共用。 ② 当Acceptor接收到Prepare消息后,必须对多个Instance同时做出回应,这通常可以通过将反馈信息封装在一个数据包中来实现,假设最多允许K个Instance同时进行提议值的选定,那么: -当前之多存在K个未达成一致的Instance,将这些未决的Instance各自最后接受的提议值封装进一个数据包,并作为Promise消息返回。 -同时,判断N是否大于当前Acceptor的highestPromisedNum值(当前已经接受的最大的提议编号值),如果大于,那么就标记这些未决Instance和所有未来的Instance的highestPromisedNum的值为N,这样,这些未决Instance和所有未来Instance都不能再接受任何编号小于N的提议。 ③ Master对所有未决Instance和所有未来Instance分别执行Propose->Accept阶段的处理,如果Master能够一直稳定运行的话,那么在接下来的算法运行过程中,就不再需要进行Prepare->Promise处理了。但是,一旦Master发现Acceptor返回了一个Reject消息,说明集群中存在另一个Master并且试图使用更大的提议编号发送了Prepare消息,此时,当前Master就需要重新分配新的提议编号并再次进行Prepare->Promise阶段的处理。 可见chubby就是一个典型的Muti-Paxos算法应用,在Master稳定运行的情况下,只需要使用同一个编号来依次执行每一个Instance的Promise->Accept阶段处理。 raft和paxos区别raft要有一个leader。在选主时每个follower只能投一次,不成功随机时间下一次。有主时的共识由主来给日志编号,比较就好。follower保证稳定可替换即可。paxos leader不能那么重要(fast paxos在无冲突时甚至无leader参与),每次可以随机选,只是汇总投票,prososol是否通过由多数决定,prososol回复客户端和同步其他leaner。算是无主的模型。zap还是有leader的。zap在无主的时候选举算法和fast paxos很像,有最大xid(类似pre阶段,只不过是上次存好的),每次投票直接给acceptor并且无协调者的冲突处理。在有主时,用paxos的思想先pre收集并同步信息保证一致,主处理写,多数处理成功后回复。 优势就是单主能不能抗住了。 zookeeperZookeeper对于每个节点QuorumPeer的设计相当的灵活,QuorumPeer主要包括四个组件:客户端请求接收器(ServerCnxnFactory)、数据引擎(ZKDatabase)、选举器(Election)、核心功能组件(Leader/Follower/Observer不同) 采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。 本身的数据组织以文件形式。 作用1.单独zk集群元数据的可靠性和一致性保证,元数据保存在zk所有副本中(少量完全可以放在内存中数据)路由,选择数据库,调度程序2.单独zk集群,锁,防护令牌,获取锁或者zxid 3.变更通知,每个变更都会发送到所有节点watch机制4.用于检测,服务发现session:每个ZooKeeper客户端的配置中都包括集合体中服务器的列表。在启动时,客户端会尝试连接到列表中的一台服务器。如果连接失败,它会尝试连接另一台服务器,以此类推,直到成功与一台服务器建立连接或因为所有ZooKeeper服务器都不可用而失败。只要一个会话空闲超过一定时间,都可以通过客户端发送ping请求(也称为心跳)保持会话不过期。ping请求由ZooKeeper的客户端库自动发送,因此在我们的代码中不需要考虑如何维护会话。这个时间长度的设置应当足够低,以便能档检测出服务器故障(由读超时体现),并且能够在会话超时的时间段内重新莲接到另外一台服务器。 zookeeper数据同步过程:zab protocol Leader election leader选举过程,electionEpoch自增,在选举的时候lastProcessedZxid越大,越有可能成为leaderDiscovery: 第一:leader收集follower的lastProcessedZxid,这个主要用来通过和leader的lastProcessedZxid对比来确认follower需要同步的数据范围 第二:选举出一个新的peerEpoch,主要用于防止旧的leader来进行提交操作(旧leader向follower发送命令的时候,follower发现zxid所在的peerEpoch比现在的小,则直接拒绝,防止出现不一致性)Synchronization: follower中的事务日志和leader保持一致的过程,就是依据follower和leader之间的lastProcessedZxid进行,follower多的话则删除掉多余部分,follower少的话则补充,一旦对应不上则follower删除掉对不上的zxid及其之后的部分然后再从leader同步该部分之后的数据Broadcast 正常处理客户端请求的过程。leader针对客户端的事务请求,然后提出一个议案,发给所有的follower,一旦过半的follower回复OK的话,leader就可以将该议案进行提交了,向所有follower发送提交该议案的请求,leader同时返回OK响应给客户端实际上zookeeper中算法三阶段:FSE=>Recovery=>Broadcast(广播和上面的一致) fast leader election基于fast paxos。发送给所有的节点。没有随机leader参与收集。 LOOKING:进入leader选举状态FOLLOWING:leader选举结束,进入follower状态LEADING:leader选举结束,进入leader状态OBSERVING:处于观察者状态1.serverA首先将electionEpoch自增,然后为自己投票2 serverB接收到上述通知,然后进行投票PK如果serverB收到的通知中的electionEpoch比自己的大,则serverB更新自己的electionEpoch为serverA的electionEpoch如果该serverB收到的通知中的electionEpoch比自己的小,则serverB向serverA发送一个通知,将serverB自己的投票以及electionEpoch发送给serverA,serverA收到后就会更新自己的electionEpoch在electionEpoch达成一致后,就开始进行投票之间的pk,优先比较proposedEpoch,然后优先比较proposedZxid,最后优先比较proposedLeaderpk完毕后,如果本机器投票被pk掉,则更新投票信息为对方投票信息,同时重新发送该投票信息给所有的server。如果本机器投票没有被pk掉,如果是looking,过半更改状态,如果FOLLOWING/LEADING说明落后,加速收敛Recovery略:https://my.oschina.net/pingpa...follower读写过程图: ectd

April 26, 2019 · 1 min · jiezi

从濒临解散到浴火重生OceanBase-这十年经历了什么

阿里妹导读:谈及国产自研数据库,就不得不提 OceanBase。与很多人想象不同的是,OceanBase 并非衔着金钥匙出生的宠儿。相反,它曾无人看好、困难重重,整个团队甚至数度濒临解散。从危在旦夕到浴火重生,OceanBase 这十年经历了什么?今天,我们一起了解它背后不为人知的故事。 OceanBase 是完全由阿里巴巴和蚂蚁金服自主研发、全球首个应用于金融核心业务的分布式关系数据库。OceanBase 的研发始于 2010 年 6 月,因为选择从零开始,研发之路从一开始就磨难重重,中途因为找不到愿意使用的业务,团队曾经濒临解散。 最终 OceanBase 还是跨越了死亡之谷,在蚂蚁金服实现了全面替代 Oracle,成功支撑了过去 5 年“双 11”蚂蚁金服全部核心业务的重压,创造了 25.6 万笔 / 秒支付峰值和 4200 万笔 / 秒请求数处理峰值这一业内全新的纪录。自 2017 年开始,OceanBase 开始走向外部商用,目前已经在数十家商业银行落地,其中包括南京银行、浙商银行、苏州银行、人保健康险等。OceanBase 帮助南京银行共同打造“鑫云 +”互金开放平台,实现贷款交易处理能力 10 倍提升,轻资产模式显著降低成本,从原有的 30~50 元 / 账户降低到上线后的 4 元 / 账户。日处理百万笔放款,平均处理时间小于 1 秒,让老百姓借钱更方便,真正实现了普惠金融。 站在现在这个时间点上顾盼今昔,蚂蚁金服高级研究员、OceanBase 创始人阳振坤认为,OceanBase 的成功其实有行业和时代的必然性。 时 机2009 年开始,大量新的非关系型数据库如雨后春笋般涌出,在整个数据库行业掀起了一场空前盛大的 NoSQL 革命,如今赫赫有名的 Redis、MongoDB 皆诞生于那一年。NoSQL 的拥护者们积极提倡使用非关系型的数据存储,从而获得丰富而随需应变的可伸缩性。这时候的关系数据库早已过了而立之年,在此期间虽然曾短暂爆发过一些所谓终结关系数据库的革命,但最终都失败了,丝毫没有动摇到关系数据库的主导地位。 但这一次似乎与以往不同,火热发展的云计算带来了对更大规模数据库的需求,而关系数据库的缺点则相应地被越来越多人诟病:不能够扩展、容量小、处理能力不够、成本又非常高。在当时的很多人看来,关系数据库的末日是真的要来了。2010 年,NoSQL 革命愈演愈烈,有行业专家发文直指“云计算时代属于 NoSQL,关系数据库已经日薄西山”。 那时阳振坤已经做了两年多的自研分布式系统,十分看好云计算系统的发展机会。同一年,阳振坤加入阿里巴巴,开始了分布式关系数据库 OceanBase 的研发。 数据库从诞生起已经有几十年的时间了,但基本上它的市场格局就没有多少变化,最早起来的几家厂商今天还是占据着统治地位。因为数据库非常难被替换,它处在整个产品或者产业链最底层的位置,替换风险很大,但收益相比起来却小得多。这也是为什么像 IBM、微软这样的后来者也无法取代 Oracle。这就导致了数据库变成了一个门槛极高、强者恒强的领域,后来者很难居上。前有 Oracle 挡道、后有 NoSQL 数据库追赶,在大部分人看来,那时候怎么也不会是自研关系数据库的好时机,但阳振坤却不这么想。 ...

April 26, 2019 · 2 min · jiezi

一份还热乎的蚂蚁金服面经已拿Offer附答案

本文来自我的知识星球的球友投稿,他在最近的校招中拿到了蚂蚁金服的实习生Offer,整体思路和面试题目由作者——泽林提供,部分答案由Hollis整理自知识星球《Hollis和他的朋友们》中「直面Java」板块。 经历了漫长一个月的等待,终于在前几天通过面试官获悉已被蚂蚁金服录取,这期间的焦虑、痛苦自不必说,知道被录取的那一刻,一整年的阴霾都一扫而空了。 笔者面的是阿里的Java研发工程师岗,面试流程是3轮技术面+1轮hr面。 意外的一面一面的时候大概是3月12号,面完等了差不多半个月才突然接到二面面试官的电话。一面可能是简历面,所以问题比较简单。 ArrayList和LinkedList区别 ArrayList 是一个可改变大小的数组.当更多的元素加入到ArrayList中时,其大小将会动态地增长.内部的元素可以直接通过get与set方法进行访问,因为ArrayList本质上就是一个数组. LinkedList 是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList. 当然,这些对比都是指数据量很大或者操作很频繁的情况下的对比,如果数据和运算量很小,那么对比将失去意义. 什么情况会造成内存泄漏 在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点: 首先,这些对象是可达的,即在有向图中,存在通路可以与其相连; 其次,这些对象是无用的,即程序以后不会再使用这些对象。 如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。 什么是线程死锁,如何解决 产生死锁的条件有四个: 1.互斥条件:所谓互斥就是进程在某一时间内独占资源。 2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。 4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 线程死锁是因为多线程访问共享资源,由于访问的顺序不当所造成的,通常是一个线程锁定了一个资源A,而又想去锁定资源B;在另一个线程中,锁定了资源B,而又想去锁定资源A以完成自身的操作,两个线程都想得到对方的资源,而不愿释放自己的资源,造成两个线程都在等待,而无法执行的情况。 要解决死锁,可以从死锁的四个条件出发,只要破坏了一个必要条件,那么我们的死锁就解决了。在java中使用多线程的时候一定要考虑是否有死锁的问题哦。 红黑树是什么?怎么实现?时间复杂度 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树。 红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键值,小于等于右孩子的键值。 除了具备该特性之外,红黑树还包括许多额外的信息。 红黑树的每个节点上都有存储位表示节点的颜色,颜色是红(Red)或黑(Black)。 红黑树的特性: (1) 每个节点或者是黑色,或者是红色。 (2) 根节点是黑色。 (3) 每个叶子节点是黑色。 (4) 如果一个节点是红色的,则它的子节点必须是黑色的。 (5) 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。 关于它的特性,需要注意的是: 第一,特性(3)中的叶子节点,是只为空(NIL或null)的节点。 第二,特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。 具体实现代码这里不贴了,要实现起来,需要包含的基本操作是添加、删除和旋转。在对红黑树进行添加或删除后,会用到旋转方法。旋转的目的是让树保持红黑树的特性。旋转包括两种:左旋 和 右旋。 红黑树的应用比较广泛,主要是用它来存储有序的数据,它的查找、插入和删除操作的时间复杂度是O(lgn)。 TCP三次握手 三次握手(three times handshake;three-way handshake)所谓的“三次握手”即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立虚连接。 为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。TCP总是用来发送大批量的数据。当应用程序在收到数据后要做出确认时也要用到TCP。 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。 突如其来的二面一面的时候大概是3月12号,面完等了差不多半个月才突然接到二面面试官的电话。 介绍项目 Storm怎么保证一致性 Storm是一个分布式的流处理系统,利用anchor和ack机制保证所有tuple都被成功处理。如果tuple出错,则可以被重传,但是如何保证出错的tuple只被处理一次呢?Storm提供了一套事务性组件Transaction Topology,用来解决这个问题。 Transactional Topology目前已经不再维护,由Trident来实现事务性topology,但是原理相同。 参考:https://cloud.tencent.com/info/5721fb4532f6a72ed2e563f9449fd025.html 说一下hashmap以及它是否线程安全 ...

April 26, 2019 · 2 min · jiezi

阿里45K高级Java岗必备技能清单

相信你可能经历过这些: 已经工作两三年了,每个项目都会加班加点全力以赴去完成,薪资增长幅度却不如人意。听说年后离职的老同事,金三刚拿下高薪offer,年薪直奔50万了。 由于现在的公司接触不到新技术,对自己的市场竞争力无比焦虑,未来职业道路怎么走? 这个凛冽寒冬,你终于明白,现在的工作机会很少,薪资很难有较大涨幅,Java工程师的年薪是技能决定的,是时候去提高技能,提前规划未来职业发展路径了。 作为Java工程师的你,平时工作已经很忙了,到底该如何进阶,才能快速提高薪资到45万甚至100万呢? 分享一些过来人的经验,供大家参考。 一朝成为Java工程师,就注定终身学习。在James的13年的Java工程师生涯中,这一点深有体会,而让我坚持学习的动力,主要源于以下三个方面: 1、 不断增值自己,拥有更多选择权如果将技术比做一棵树,每学会一门语言,就点亮树上一个果实,你会得越多,技术树的果实就越多,价值就越大。当技术树的果实积累到一定程度,你就能纵向往高阶技术方向晋级,职业发展之路更上一层楼。 2、 互联网没有舒适圈,止步不前便是退步计算机技术更新迭代快、新技术层出不穷,如果想要成为一个优秀的Java工程师,就要做好随时学习的准备,并持之以恒,这样才能跟上互联网日新月异的发展节奏。 3、 学习是面对竞争、度过中年危机的最好方法Java工程师是高薪职业,近年来互联网的高速发展下,更是一度成为抢手的热门职业,以至于投身到这个职业的人越来越多,千军万马过独木桥,想要不掉队,唯有努力学习,成为互联网公司高薪争抢的中高端Java工程师,才能不惧寒冬。 2018年这个寒冬让很多互联网人清醒了,众多大企裁员、招聘需求收缩,主要还是针对基础岗、温水煮青蛙给煮死的那波人,中高端Java工程师在市场上依然紧缺。 下面,James为大家梳理了一份目前互联网公司的主流技术选型。 互联网公司主流技术选型进阶高级Java、架构师必学6大主要技能,包括:数据结构和算法、Java高级特性、Java web核心、数据库、Java框架与必备工具、系统架构设计等,希望能真正帮助到想要从程序员进阶为高级Java、架构师之路的朋友。 1、并发编程通过深入了解最底层的运作原理,加强逻辑思维,才能编写出高效、安全的多线程并发程序。 包括:集合框架(源码)、工具类、框架Spring、SpringMVC、Mybatis、Shiro、Netty、服务器(tomcat、Nginx)、网络编程、序列化、JVM等。 2、设计模式设计模式是可复用面向对象软件的基础,学习设计模试是每一位Java工程师进阶的必经之路,灵活地使用设计模式,可以让代码变得简洁、易懂、复用性更高。 常见常用的设计模式有:工厂模式、代理模式等。 3、分布式架构随着业务体量及重要性的增大,单体架构模式无法对应大型应用场景,系统也决不允许存在单点故障导致整体不可用,所以只有垂直或水平拆分业务系统,形成一个分布式的架构来消除单点故障,从而提高整个系统的可用性。 包括:分布式Session、分布式缓存、数据库、一致性、负载均衡、消息队列(RabbitMQ、ZeroMQ、Kafka)等 4、微服务因时因地制宜,选择使用微服务架构的收益将远远大于成本。 规模较少的企业可以考虑适当引入合适的微服务架构,改造已有系统或新建微服务应用,逐步积累微服务架构经验,不要全盘实施微服务架构,综合考量成本与效率、实用性。 5、JVM性能优化 最后,James想说,职场也好,人生也罢,每个阶段都有一定的阻碍与瓶颈,这是我们都要经历的。 如果你能够认清自己以及自己所处的阶段,有针对性的去思考、充电,坚持做正确的事,付出比别人更多的努力,你就会比别人更加优秀,拥有更多的机会,这就是我们常说的马太效应:越努力,越幸运。 BAT面试真题+架构技术资料,提升软硬实力,收获高薪好offer说了这么多,到底该如何学习呢,有没有资料或视频呀? James潜心两年,专注Java面试通关、进阶架构师,不仅提供“知识”,更关注和强调从“知识获得”到“实战能力提升”的转化过程。坚持创作的BAT架构技术系列专题500+、面试资料库1000+,需要的可以私信:“架构”免费获取,供大家参考进阶。

April 25, 2019 · 1 min · jiezi

分布式系统关注点18缓存穿透和缓存雪崩到底啥区别

如果第二次看到我的文章,欢迎文末扫码订阅我个人的公众号(跨界架构师)哟~ 本文长度为2805字,建议阅读8分钟。坚持原创,每一篇都是用心之作~ 有句话说得好,欲要使其毁灭,先要使其疯狂。当你沉浸在缓存所带来的系统tps飙升的喜悦中时,使你系统毁灭的种子也已经埋在其中。 而且,你所承载的tps越高,它所带来的毁灭性更大。 在前两篇《360°全方位解读「缓存」》和《先写DB还是「缓存」?》中,我们已经对缓存有了一定的认识,并且知道了关于缓存相关的「一致性」问题的最佳实践。 这次,我们就来聊聊隐藏在缓存中的毁灭性种子是什么? 我们从前一篇文章《先写DB还是「缓存」?》中多次提到的「cache miss」说起。 缓存雪崩在前一篇文章《先写DB还是「缓存」?》中,我们多次提到了「cache miss」这个词,利用「cache miss」来更好的保障DB和缓存之间的数据一致性。 然而,任何事物都是有两面性的,「cache miss」在提供便利的同时,也带来了一个潜在风险。 这个风险就是「缓存雪崩」。 在图中的第二步,大量的请求并发进入,这里的一次「cache miss」就有可能导致产生「缓存雪崩」。 不过,虽然「cache miss」会产生「缓存雪崩」,但「缓存雪崩」并不仅仅产生于「cache miss」。 雪崩一词源于「雪崩效应」,是指像「多米勒骨牌」这样的级联反应。前面没顶住,导致影响后面,如此蔓延。(关于对应雪崩的方式参考之前的文章,文末放链接) 所以「缓存雪崩」的根本问题是:缓存由于某些原因未起到预期的缓冲效果,导致请求全部流转到数据库,造成数据库压力过重。 因此,流量激增、高并发下的缓存过期、甚至缓存系统宕机都有可能产生「缓存雪崩」问题。 怎么解决这个问题呢?宕机可以通过做高可用来解决(可以参考之前的文章,文末放链接)。而在“流量激增”、“高并发下的缓存过期”这两种场景下,也有两种方式可以来解决。 加锁排队通过加锁或者排队机制来限制读数据库写缓存的线程数量。比如,下面的伪代码就是对某个key只允许一个线程进入的效果。 key = "aaa";var cacheValue = cache.read(key);if (cacheValue != null) { return cacheValue;}else { lock(key) { cacheValue = cache.read(key); if (cacheValue != null) { return cacheValue; } else { cacheValue = db.read(key); cache.set(key,cacheValue); } } return cacheValue;} 这个比较好理解,就不废话了。 ...

April 25, 2019 · 1 min · jiezi

阿里新一代分布式任务调度平台Schedulerx20破土而出

1. 产品简介Schedulerx2.0是阿里中间件自研的基于Akka架构的新一代分布式任务调度平台,提供定时、任务编排、分布式跑批等功能。使用Schedulerx2.0,您可以在控制台配置管理您的定时任务,查询历史执行记录,查看运行日志。借助Schedulerx2.0,您还可以通过工作流进行任务编排和数据传递。Schedulerx2.0还提供了简单易用的分布式编程模型,简单几行代码就可以将海量数据分布式到多台机器上执行。 Schedulerx2.0提供了任务调度与执行的一整套解决方案,在阿里巴巴集团内部广泛使用并久经考验,具有高可靠、海量任务、秒级别调度等能力。 上线时间:2019-04-30 2. 背景Schedulerx2.0是Schedulerx1.0(DTS)的下一代产品,采用全新的架构,是全新自研的下一代分布式任务调度平台,不但解决了老产品的性能瓶颈,还提供了更多更快更强的能力。 更多:支持多种时间表达式,任务编排,支持更多的业务场景。单集群支持上千万任务,一天上十亿次调度,支持更多的任务数。更快:支持秒级别调度,处理准实时业务。更强:支持日志查询、原地重跑、重刷数据等多种操作,提供更强的运维能力和排错手段,解决为什么没跑,为什么失败,为什么跑得慢等问题。3. 功能3.1 强大的定时调度器3.1.1 Crontab 支持unix crontab表达式,不支持秒级别。 3.1.2 Fixed rate 众所周知,crontab必须被60整除,比如想每隔40分钟跑一次,cron不支持。Fixed rate专门用来做定期轮询,表达式简单,不支持秒级别。 3.1.3 Fixed delay 适合对实时性要求比较高的业务,比如每次执行完成隔10秒再跑,那么second delay非常适合你。并且second delay能支持到秒级别。 3.1.4 日历 支持多种日历,还可以自定义导入日历。比如金融业务需要在每个交易日执行。 3.1.5 时区 跨国的业务,需要在每个国家的时区定时执行某个任务。 3.2 任务编排支持工作流(DAG)进行任务编排,操作简单,前端直接单手操作拖拖拽拽即可。详细的任务状态图能一目了然看到下游任务为什么没跑。 3.3 任务类型支持多种任务类型,可以无限扩展。 java:可以跑在用户进程中,也可以上传jar包动态加载。shell:前端直接写shell脚本。python:前端直接写python脚本,需要机器有python环境。go:前端直接写go脚本,需要机器有go环境。自定义:用户甚至可以自定义任务类型,然后实现一个plugin就行了。3.4 执行方式&分布式编程模型3.4.1 执行方式 单机:随机挑选一台机器执行广播:所有机器同时执行且等待全部结束并行计算:map/mapreduce模型,1~300个子任务,有子任务列表。内存网格:map/mapreduce模型,10W以下子任务,无子任务列表,基于内存计算,比网格计算快。网格计算:map/mapreduce模型,100W以下子任务,无子任务列表,基于文件H2计算。3.4.2 分布式编程模型 Map模型:类似于hadoop mapreduce里的map。只要实现一个map方法,简单几行代码就可以将海量数据分布式到客户自己的多台机器上执行,进行跑批。MapReduce模型:MapReduce模型是Map模型的扩展,新增reduce接口,所有子任务完成后会执行reduce方法,可以在reduce方法中返回该任务实例的执行结果,或者回调业务。3.5 强大的运维能力数据大盘:控制台提供了执行记录大盘和执行列表,可以看到每个任务的执行历史,并提供操作。查看日志:每条执行记录,都可以详情中的日志页面实时看到日志。如果任务运行失败了,前端直接就能看到错误日志,非常方便。原地重跑:任务失败,修改完代码发布后,可以点击原地重跑。标记成功:任务失败,如果后台把数据处理正确了,重跑又需要好几个小时,直接标记成功就好了。Kill:实现JobProcessor的kill()接口,你就可以在前端kill正在运行的任务,甚至子任务。3.6 数据时间Schedulerx2.0可以处理有数据状态的任务。创建任务的时候可以填数据偏移。比如一个任务是每天00:30运行,但是实际上要处理上一天的数据,就可以向前偏移一个小时。运行时间不变,执行的时候通过context.getDataTime()获得的就是前一天23:30。 3.7 重刷数据既然任务具有了数据时间,一定少不了重刷数据。比如一个任务/工作流最终产生一个报表,但是业务发生变更(新增一个字段),或者发现上一个月的数据都有错误,那么就需要重刷过去一个月的数据。 通过重刷数据功能,可以重刷某些任务/工作流的数据(只支持天级别),每个实例都是不同的数据时间。 3.8 失败自动重试实例失败自动重试:在任务管理的高级配置中,可以配置实例失败重试次数和重试间隔,比如重试3次,每次间隔30秒。如果重试3次仍旧失败,该实例状态才会变为失败,并发送报警。子任务失败自动重试:如果是分布式任务(并行计算/内网网格/网格计算),子任务也支持失败自动重试和重试间隔,同样可以通过任务管理的高级配置进行配置。3.9 支持原生Spring之前的老产品Schedulerx1.0(DTS)和spring的结合非常暴力,对bean的命名有强要求,经常遇到注入失败的问题。Schedulerx2.0支持原生spring语法,接入更加的方便。 3.10 报警监控失败报警超时报警报警方式:短信 本文作者:黄晓萌阅读原文 本文为云栖社区原创内容,未经允许不得转载。

April 24, 2019 · 1 min · jiezi

源码|详解分布式事务之 Seata-Client 原理及流程

摘要: 本文主要基于 spring cloud + spring jpa + spring cloud alibaba fescar + mysql + seata 的结构,搭建一个分布式系统的 demo,通过 seata 的 debug 日志和源代码,从 client 端(RM、TM)的角度分析其工作流程及原理。前言在分布式系统中,分布式事务是一个必须要解决的问题,目前使用较多的是最终一致性方案。自年初阿里开源了Fescar(四月初更名为Seata)后,该项目受到了极大的关注,目前已接近 8000 Star。Seata以高性能和零侵入的特性为目标解决微服务领域的分布式事务难题,目前正处于快速迭代中,近期小目标是生产可用的 Mysql 版本。 本文主要基于 spring cloud + spring jpa + spring cloud alibaba fescar + mysql + seata 的结构,搭建一个分布式系统的 demo,通过 seata 的 debug 日志和源代码,从 client 端(RM、TM)的角度分析其工作流程及原理。(示例项目:https://github.com/fescar-group/fescar-samples/tree/master/springcloud-jpa-seata) 为了更好地理解全文,我们来熟悉一下相关概念: XID:全局事务的唯一标识,由 ip:port:sequence 组成;Transaction Coordinator (TC):事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚;Transaction Manager (TM ):控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议;Resource Manager (RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚;提示:文中代码是基于 fescar-0.4.1 版本,由于项目刚更名为 seata 不久,其中一些包名、类名、jar包等名称还没统一更换过来,故下文中仍使用 fescar 进行表述。分布式框架支持Fescar 使用 XID 表示一个分布式事务,XID 需要在一次分布式事务请求所涉的系统中进行传递,从而向 feacar-server 发送分支事务的处理情况,以及接收 feacar-server 的 commit、rollback 指令。 Fescar 官方已支持全版本的 dubbo 协议,而对于 spring cloud(spring-boot)的分布式项目社区也提供了相应的实现 ...

April 23, 2019 · 11 min · jiezi

提升不止一点点,Dubbo 3.0 预览版详细解读

Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网、网易考拉等互联网公司,也不乏中国人寿、青岛海尔等大型传统企业。更多用户信息,可以访问Dubbo @GitHub,issue#1012: Wanted: who's using dubbo。 自去年 12 月开始,Dubbo 3.0 便已正式进入开发阶段,并备受社区和广大 Dubbo 用户的关注,本文将为您详细解读 3.0 预览版的新特性和新功能。 下面先解答一下两个有意思的与 Dubbo 相关的疑问。 为什么 Dubbo 一开源就是 2.0 版本?之前是否存在 1.0 版本?笔者曾做过 Dubbo 协议的适配兼容,Dubbo 确实存在过 1.x 版本,而且从协议设计和模型设计上都与 2.0 的开源版本协议是完全不一样的。下图是关于 Dubbo 的发展路径: 阿里内部正在使用 Dubbo 开源版本吗?是的,非常确定,当前开源版本的 Dubbo 在阿里巴巴被广泛使用,而阿里的电商核心部门是用的 HSF2.2 版本,这个版本是兼容了 Dubbo 使用方式和 Remoting 协议。当然,我们现在正在做 HSF2.2 的升级,直接依赖开源版本的 Dubbo 来做内核的统一。所以,Dubbo 是得到大规模线上系统验证的分布式服务框架,这一点毋容置疑。 Dubbo 3.0 预览版的要点Dubbo 3.0 在设计和功能上的新增支持和改进,主要是以下四方面: Dubbo 内核之 Filter 链的异步化这里要指出的是,3.0 中规划的异步去阻塞和 2.7 中提供的异步是两个层面的特性。2.7 中的异步是建立在传统 RPC 中 request – response 会话模型上的,而 3.0 中的异步将会从通讯协议层面由下向上构建,关注的是跨进程、全链路的异步问题。通过底层协议开始支持 streaming 方式,不单单可以支持多种会话模型,还可以在协议层面开始支持反压、限流等特性,使得整个分布式体系更具有弹性。综上所述,2.7 关注的异步更局限在点对点的异步(一个 consumer 调用一个 provider),3.0 关注的异步化,宽度上则关注整个调用链上的异步,高度上则向上又可以包装成 Rx 的编程模型。有趣的是,Spring 5.0 发布了对 Flux 的支持,随后开始解决跨进程的异步问题。 ...

April 22, 2019 · 6 min · jiezi

TiDB 在银行核心金融领域的研究与两地三中心实践

作者介绍:于振华,北京银行软件开发部资深架构师,长期从事银行核心系统研发、规划,参与过多个核心信息系统建设工作,包括一、二代支付系统、第四代银行核心系统建设、分布式核心系统建设等企业级项目工作。当前主要研发方向集中在构建先进、高效、面向 OLTP 的银行交易系统,提升银行信息系统服务能力。本文整理自于振华老师在 TiDB DevCon 2019 上的演讲实录,演讲主题为《TiDB 在银行核心金融领域的研究与实践》。今天参加 TiDB DevCon 2019 能够和这么多各行各业的朋友一起来交流 TiDB 的实践情况,这个机会非常难得,因为平时都是我们技术团队和 TiDB 团队单向的交流,横向的这种客户之间交流的机会很少,像刚才几位老师讲的,我觉得都很有意思,也希望通过咱们这次大会,大家能擦出不一样的火花。北京银行和 PingCAP 团队进行了深度的合作,目前有几套重要的实时交易类系统已经对接,包括比较重要网联系统、银联无卡支付、金融互联服务平台等。现在怎么来评价一款产品到底稳不稳,很大程度上要看这款产品在金融,尤其是核心金融的场景有没有应用,能不能支持金融场景的要求。我们是在 2018 年 3 月份、5 月份、6 月份进行了投产。经过半年多的时间,我们看到 TiDB 也能够支持金融场景了。从侧面来讲,分布式数据库技术,确实已经到达了一定的成熟度。一、背景介绍我相信这几年,尤其是这三四年,大家应该都有感触。无论是工作方式,还是生活方式,都发生了很大的变化,各种信息、科技产品铺面而来,有人说是这种变化叫工业科技革命 4.0。不知道这种提法准确不准确,但这种变化确实对我们银行的系统产生了比较大的挑战。<center>图 1</center>在图 1 中 ,我列出了几项,比如高并发的要求,要求你具备很快的扩展能力。再比如产品发布,要求你具备快速的发布能力,在座的应该有很多做产品、做实施的团队,大家应该很有感触,比如可能前一天还无人问津的产品,第二天可能就会卖的很火爆,来的每个项目都是紧急项目,都要求你在最快的时间发布出去。当然还包括一些老生常谈的问题,像传统架构成本难以控制,还有自主可控亟待攻关,其实在传统闭源的生态里面,我们很难达到自主可控的要求。二、系统分析<center>图 2</center>在这种背景下,我们从全局的角度出发,对银行以往的技术形态做了系统性的分析,图 2 中列举了一些典型的架构形态,有一些在现在的银行架构里边还是存在的,比如单体的应用,再比如传统的数据库,现在用的最多的 DB2 和 Oracle,还有传统的单机或者集群部署模式,以及瀑布开发模型,当然还有面向传统架构的运维模式。今天我们来谈分布式数据库,它是一个新技术,但不能说把以往技术架构就否定掉。以往的技术形态好不好?坦白讲,我认为很好,不好的话不可能支撑了这么多年的金融业务发展,但站在今天这样的时间点来说问题也是存在的。像刚才讲到的,高并发的要求、扩展能力、成本、以及产品交付能力都存在一些不尽如人意的地方。在这种情况下,我们启动了北京银行新一轮的架构转型的工作,分布式数据库也纳入到我们的工作范围里。我们和 PingCAP 很早就接触了,在一年多的工作过程中,要谈的技术细节、技术方案、工作流程等等这些内容会很多,如果真的来总结一下这项工作是怎么做的话,我总结出以下三条。大家一看可能会觉得很虚,但是你如果真的来实践这件事,也许会有同样的感触。第一个就是「务实」。架构转型不是一个为了技术而技术,为了新产品而新产品的工作,而是确实要对你的业务发展、开发、运维的效率有所提升。第二个,我觉得可能是最重要的,就是要做到「速赢」。无论是你在什么样的企业来做技术升级,技术转型,或多或少的都会遇到一些阻力,尤其是在传统企业。那做到速赢,迅速的释放价值,让你周围的人、让你的团队、让你的组织,迅速看到它的价值,会让你未来的工作开展更加平滑。第三个是「全栈」。因为是整体的架构转型工作,我们希望建设一套平台,它能够释放整体的价值,而不是在乎一城一池的得失。今天本来我想介绍北京银行的应用架构和分布式数据库架构,因为时间关系今天只说一下分布式数据库建设的情况。三、进展情况<center>图 3</center>在介绍具体内容之前,先跟大家同步一下,我们现在的工作进展。2018 年 3 月,我们投产了行业内首个面向核心金融业务的分布式数据库,采用的是两地三中心五副本的架构模式。以分布式数据库为基础,5 月份我们投产了网联支付清算平台,这也是很重要的一个带资金业务的实时交易系统,6 月份投产了银联无卡支付平台。这张图(图 3)可能稍微有点老,现在我们投产的还包括金融互联服务平台,IFRS9 减值系统。我们未来要做的事其实和刚才刘奇讲的比较一致,包括 HTAP,包括容器云的这些方案等等,这也是我们目前最迫切的需求。3.1 专项评测现在回想起来,北京银行开展分布式数据库建设的工作,其实是在行业里面算很早的,也是因为我们开展这件工作的时间比较早,所以在整个过程中遇到了很多的困难困惑。行里的技术力量集中在 DB2、Oracle 上可能比较多,对于分布式数据库的掌握来讲,需要有一个周期。我们做的第一步,为了保证产品可用,建设了面向金融业务的评测体系。<center>图 4</center>图 4 左上角是面向这个功能的测试,比如数据库有没有高可用性,能不能做线性扩展,有没有在线升级能力,这些都是我们的测试点。图 4 左下角这块,是面向性能的测试,我们并没有采用市面上已经有的工具,比如 TPCC、Sysbench 等等。因为我们实际分析下来觉得市面已经有的这些工具和我们的金融场景有一些距离,用它们来测试可能不会有很好的参考意义,所以我们自研了这套面向分布式数据库的金融性能评测体系,能够让我们明确出分布式数据库可以应用在金融场景,并且对于功能和性能,让大家能有一个可度量的工具。在这个过程中,要感谢支付清算协会、信通院等上级单位和组织给予我们的帮助,另外,我们也和硬件厂商英特尔进行了比较深的合作,比如今年(2018 年)新的硬件平台,我们也做了专项的分布式数据库测试,为未来我们硬件的架构选型提供了有效的参考。3.2 部署模式<center>图 5</center>对于分布式数据库的技术层面来讲,刚才几位讲师介绍的比较多了,我就来讲一些北京银行比较不一样的、走在前面的一些地方。 大家看到图 5 这套架构是北京银行的数据存储层的架构。北京银行的架构采用两地三中心五副本的模式部署。跨城长距离的分布式数据库建设具有很大的挑战。比如北京和西安大概一千多公里,两地距离比较远,延时比较高,我们实测的延时大概是十七毫秒左右。这十七毫秒,如果放在一条 SQL 来讲,一来一回三十几毫秒,这样的延时我们肯定是接受不了。所以在这种情况下,我们用了一个五副本的模式:北京两个 IDC,各放置两副本,西安一个 IDC 放置一个副本,采用 2:2:1 的模式。这样做的好处就是当前端应用请求过来之后,不需要用到北京到西安的这个网络,北京的四个副本中成功三个,就可以给前端实时返回,而且北京的部分实例允许失效。这样做 SQL 平均延时,大概在 1.2 毫秒左右,.95 延时大概 5 毫秒左右,这是比较不错的一个成绩(网联、银联的业务其实要比互联网业务复杂很多)。这里给大家分享一个我们实际在生产过程中遇到的一个小故事。在某个周六的中午我接到我们运维值班人员的电话,他说 TiKV 存储服务器坏了一台,当日我第一时间问的是:坏了一台有没有影响服务。他说没有影响服务,服务还是正常的。我说那就赶紧找硬件厂商给修一下机器。当时还觉得挺高兴的,不经意间在生产系统验证了一把。到了第二天周日的中午,他又给我打了一个电话,说又坏了一台服务器。当时有一些担心,是不是我们这批采购的硬件服务器有什么问题,想到这点就立马做排查,当然第一时间问的还是有没有影响服务,他说没有影响服务。这样连着两天坏了两台存储服务器都没有影响服务,也证明了多副本方案的有效性。3.3 两地三中心<center>图 6</center>图 6 展示的是整个包括应用、F5 到 TiDB、PD、TiKV 等整个部署的模式。目前我们接着有网联、银联这两个比较大的系统,这两个系统业务量相对来讲比较大,每天有一两百万笔的业务。在西安,我们还部署了一个从集群,那这个从集群是做什么呢?这个从集群就是为了对接一些 OLAP 或者说比较大的报表的情况,从而避免它对主集群的负载产生过大的影响。四、应用实践4.1 出现过的问题<center>图 7</center>有人说“当你有了锤子,好像什么问题都看上去像钉子”。我们期待从传统数据库过渡到分布式数据库,什么问题都可以解决。但事实上,肯定是没有一个万能的技术方案。图 7 右下角,我列了一些从我们项目开展之初到现在,产生一些问题或者说一些小插曲。比如我们刚才介绍了行里的 DB2、Oracle 应用的比较多。DB2、Oracle 以前用的是 READ COMMITTED 的隔离级别,那现在到了 TiDB 的 Repeatable Read 的这种形式可能还需要适应。我们建设初期也出现过这种问题:这边 Insert 的数据,那边却查不到,就因为 TiDB 是这种快照的隔离级别。还有执行计划的索引没有选中的问题,这个在我们实际的生产过程中也遇到过,明明有索引,却没有精确选中那一个索引。造成 SQL 运行的特别慢,内存吃的也比较多。这个问题,我觉得是可以解决好的,临时解决方案就是手动强制加 Hint,未来我相信 TiDB 在版本升级上也会考虑这一点,让执行计划更加准确。还有热点数据的问题,热点数据指望数据库来解决,现阶段来看是不可能了。无论是传统数据库,还是分布式数据库,要引入另外的应用缓存的组件才可以解决,在传统方案里边,我们做的技术方案也有很多,像比较传统的散列方式,把热点数据散列出去来解决,现在有了缓存,可以引入缓存解决这件事。我们应用架构采用微服务的形态,对比单体应用形态,微服务对于数据库的要求会更高。因为传统的单体应用,事务的 SQL 数量比较多,划分成微服务的话,无论是应用逻辑,还是数据库的处理逻辑,都会比较细粒度,事务提交次数成倍增长,对于 MVCC 的乐观提交模型有一定的压力,在我们实测的过程中,越细粒度的可能表现的性能越不好。以上就是我们实践过程中出现的一些小插曲。4.2 与互联网行业在应用实践上的区别<center>图 8</center>今天很多来自互联网企业的朋友也分享了自己的经验,那在金融行业做分布式数据库落地和互联网行业有什么不同呢?首先来讲,银行的发展时期和很多互联网新兴科技公司是不同的,银行有很成熟的硬件体系、部署模式、软件的设计模式、开发模式、运维模式,站在这种平台上来做新型技术落地会更加的困难。为什么会得到这个结论?因为现在也有很多的软件厂商,很多做产品的人,大家都希望做新建系统的事情。但对于庞大的历史系统做迁移的话,肯定不会是一刀切的方案,因为代价太大了。所以需要并行运行,对于这种新旧架构并行,很多时候就没有了方案,做不了。其实现在我们也在做这项工作,做一个新旧系统优雅的并行方案,包括业务逻辑的并行,还有业务数据的并行,如果大家有兴趣的话,也可以和我们私下交流这部分内容,我觉得这是很重要的一个事情。第二点就是组织架构不同。就拿微服务来说,单体的应用发展这么多年,每一个应用它的技术负责人是谁,对应的业务负责人是谁,是哪个部门,都很明确。如果做微服务化,进行拆分,很多情况下很难确定权责,如果要企业组织架构来适应系统架构也不太现实。当然历史资产、业务场景和互联网企业也是不一样的,银行信息化历史资产更多、业务比互联网更加复杂。4.3 新型架构<center>图 9</center>图 9 是我们系统建设架构图的一部分,最底下是分布式 NewSQL 数据库的基础平台,上边是应用系统,目前是传统架构和新型微服务架构并存。五、未来展望<center>图 10</center>最后再介绍一下未来我们的建设方向。第一,经过阶段性的实践,新的架构仍需要进行多方位的验证,来确保高可用性、扩展性、成本等方面的优势。下一个阶段我们希望扩大应用范围,把业务发展快、规模大、对并发要求高的系统,逐步的迁移过去。第二,我们要建立一套应用规范,或者说面向 TiDB 的金融级开发的规范指引。目前我们正在做这个事儿,包括最佳研发应用实践以及新老架构并行方案。建设传统数据库和 TiDB 之间的异构数据库传输的中间件是我们目前很重要的一项工作,这部分做完之后,相信对我们扩大应用会比较有好处。第三,我们还要做 HTAP,这点和刚才刘奇谈到的可能会比较契合。之前我看过 TiFlash 的设计理念和设计方式,我觉得是比较新颖的一种方式,比现在有些还需要 T+1 的数据分析方案会好很多,技术架构更加一体化、业务过程更加流畅。另外,我们一直在做性能提升、网络依赖消减等工作。最后,我们也希望能够把北京银行的经验和大家多多分享,让大家不再遇到我们建设过程中遇到的问题和麻烦,更加顺畅的进行架构转型工作。以上就是我今天分享的内容,谢谢大家。 ...

April 18, 2019 · 1 min · jiezi

3分钟干货之分布式系统

分布式系统非常关注三个指标:△关于一致性数据“强一致性”,是希望系统只读到最新写入的数据,例如:通过单点串行化的方式,就能够达到这个效果。关于session一致性,DB主从一致性,DB双主一致性,DB与Cache一致性,数据冗余一致性,消息时序一致性,分布式事务一致性,库存扣减一致性。△关于可用性如果系统每运行100个时间单位,会有1个时间单位无法提供服务,则说系统的可用性是99%。可用性和可靠性是比较容易搞混的两个指标,以一台取款机为例:·正确的输入,能够取到正确的钱,表示系统可靠·取款机7*24小时提供服务,表示系统可用保证系统高可用的方法是:·冗余·故障自动转移△关于连通性与扩展性分布式系统,往往有多个节点,每个节点之间,都不是完全独立的,需要相互通信,当发生节点无法联通时,数据是否还能保持一致,系统要如何进行容错处理,是需要考虑的。同时,连通性和扩展性紧密相关,想要加机器扩展性能,必须有良好的连通性。当一个节点脱离系统,系统就出现问题,往往意味着系统是无法扩展的。

April 17, 2019 · 1 min · jiezi

蚂蚁金服高级研究员阳振坤:为什么我们要选择自研数据库这条艰难之路

“如果大家当时能看见原来十年后OceanBase能长成这样,可能十年前OceanBase得到的支持会好很多。但是这种如果是不存在的,很多时候你要先证明自己。” 根据工信部数据显示,1998年,中国软件企业5000家,市场规模325亿;到了2018年底,中国软件企业3.78万家,收入规模超过6.3万亿元,营收增长了193.8倍。可在最核心的基础设施三大件芯片、操作系统和数据库上,过去我们并未取得商用意义上的重大突破。不过,相比芯片和操作系统,国内数据库领域的局面要略微乐观一些。除了传统的数据库厂商、数据服务商,互联网巨头、云计算厂商、硬件厂商、新兴的创业公司也越来越多地投入到数据库的研发中。而谈及国产自研数据库,就不得不提OceanBase。OceanBase是完全由阿里巴巴和蚂蚁金服自主研发、全球首个应用于金融核心业务的分布式关系数据库。OceanBase的研发始于2010年6月,因为选择从零开始,研发之路从一开始就磨难重重,中途因为找不到愿意使用的业务,团队曾经濒临解散。最终OceanBase还是跨越了死亡之谷,在蚂蚁金服实现了全面替代Oracle,成功支撑了过去5年“双11”蚂蚁金服全部核心业务的重压,创造了25.6万笔/秒支付峰值和4200万笔/秒请求数处理峰值这一业内全新的纪录。自2017年开始,OceanBase开始走向外部商用,目前已经在数十家商业银行落地,其中包括南京银行、浙商银行、苏州银行、人保健康险等。OceanBase帮助南京银行共同打造“鑫云+”互金开放平台,实现贷款交易处理能力10倍提升,轻资产模式显著降低成本,从原有的3050元/账户降低到上线后的4元/账户。日处理百万笔放款,平均处理时间小于1 秒,让老百姓借钱更方便,真正实现了普惠金融。站在现在这个时间点上顾盼今昔,蚂蚁金服高级研究员、OceanBase创始人阳振坤认为,OceanBase的成功其实有行业和时代的必然性。这是最坏的时代,也是最好的时代2009年开始,大量新的非关系型数据库如雨后春笋般涌出,在整个数据库行业掀起了一场空前盛大的NoSQL革命。这时候的关系数据库早已过了而立之年,在此期间虽然曾短暂爆发过一些所谓终结关系数据库的革命,但丝毫没有动摇到关系数据库的主导地位。但这一次似乎与以往不同,火热发展的云计算带来了对更大规模数据库的需求,而关系数据库的缺点则相应地被越来越多人诟病:不能够扩展、容量小、处理能力不够、成本又非常高。在当时的很多人看来,关系数据库的末日是真的要来了。那时阳振坤已经做了两年多的自研分布式系统,他十分看好云计算系统的发展机会。同一年,阳振坤加入阿里巴巴,开始了分布式关系数据库OceanBase的研发。数据库从诞生起已经有几十年的时间了,但基本上它的市场格局就没有多少变化,最早起来的几家厂商今天还是占据着统治地位。因为数据库非常难被替换,它处在整个产品或者产业链最底层的位置,替换风险很大,但收益相比起来却小得多。这也是为什么像IBM、微软这样的后来者也无法取代Oracle。这就导致了数据库变成了一个门槛极高、强者恒强的领域,后来者很难居上。前有Oracle挡道、后有NoSQL数据库追赶,在大部分人看来,那时候怎么也不会是自研关系数据库的好时机,但阳振坤却不这么想。加入阿里之后,阳振坤发现无论对淘宝还是支付宝,关系数据库都扮演着十分关键的角色,在使用上根本不可能摆脱。但已有的数据库,无论是商业数据库还是开源数据库,都有非常多的局限,远远无法满足如淘宝、支付宝这样的互联网和金融业务对高扩展、高并发、高可用和低成本的需求。单机数据库已经走到了尽头,下一步只能走向分布式,而分布式恰好是阳振坤所擅长的。如果能将分布式技术揉到数据库里面,解决单机数据库存在的各种问题,对当时整个互联网的基础设施都会是一个巨大的帮助和进步。阳振坤认为他们赶上了一个“天时地利人和”的好机会。“天时”指的是互联网的爆发式增长对数据库的高并发、大数据量提出了很大的需求,有了需求去推动就会容易得多;“地利”指的是阿里内部从淘宝到蚂蚁金服拥有大量需要使用数据库的场景,OceanBase可以从不是特别重要的应用场景开始尝试,一步步地将数据库做成关键系统;“人和”指的是当时单机数据库已经走到了尽头,下一步一定是走向分布式,而当时团队成员大多是研究分布式出身,做的就是自己最擅长的工作。用阳振坤的原话就是:“这是千载难逢的机会,我们一定要做,而且一定能做成。”一个不断“破格”的人“一个不断破格的人”,这是早前某次采访中记者对阳振坤的评价。1984年阳振坤考入北京大学数学系,硕士师从本系的张恭庆院士,后又转向计算机领域,博士师从计算机系的王选院士。需要强调的是,他修完大学课程只用了3年,硕士只用了一年多,成为王选院士博士生的时候他只有24岁。1995年其所在团队研究成果获国家科技进步一等奖(排名第四),1997年也就是他32岁那年被破格晋升为教授。在他人或许都安于现状之时,他却毅然选择了离校。个中原因也不复杂,他的工作更偏于工程,而在工业界有更多的机会,也能发挥更大的作用。2002年离开北大/方正的时候,阳振坤内心很清楚自己必须要做点不一样的事情。他先是加入联想研究院担任首席研究员,负责无线通信领域的研究;后来接触到分布式系统并看好其前景,在微软亚洲研究院、百度所从事的工作都属于分布式这个范畴,前者侧重研究,后者偏重工程实践。回想在北大的那些年,阳振坤觉得特别感激的是,学数学让他有了一个很好的数学基础,后来转到计算机系以后,碰到了王选老师,又打下了一个比较牢靠的计算机基础,这才有了他后来的今天。作为对阳振坤影响最大的人,恩师王选有两点让他至今受益:一是如何判断一件事情是否有价值,二是“顶天立地”的技术理念,“顶天”就是技术上要不断追求新突破,“立地”就是要把技术做成通用产品,让整个社会都能普遍使用。其实2010年去淘宝的时候,阳振坤根本不知道自己会做什么事情。加入淘宝之后,摆在他面前的有两个选择,一个是加入正在快速发展的淘宝业务团队,去主管技术,这是一条已经能看到很大的发展机会、相对轻松的道路;另一条是阳振坤后来自己选的,从头组建团队做一个技术平台,也就是今天我们看到的OceanBase数据库。从加入淘宝到选择做自研数据库,一共只花了两个星期的时间。这不是一个容易的选择,但阳振坤相信自己的判断:“2010年选这个项目的时候,我是觉得这件事情需要做。当时互联网迅速发展带来了对大数据量、高并发的需求,大家对传统单机数据库有很大的抱怨,觉得它既没有扩展能力,又没有高并发的能力,成本还非常高,但是互联网根本就离不开关系数据库。这件事情怎么看都是一件应该要做、需要做的事情。”阳振坤没有说出来的是,这件事到底有多难。那时候阿里巴巴刚开始要“去IOE”,几乎没人想着说要自己从头做一个数据库。传统关系数据库都是通过外部硬件来保证可用性,用便宜的PC机替换高端服务器之后,硬件更容易出故障了,如何保证数据库高可用?高可用和数据一致性如何同时保证?分布式系统怎么同时实现CAP的要求?几十年来这么多做数据库的厂商,国内国外基本没有人成功过。而且从公司的业务发展的角度,也不可能等你几年把数据库做出来,再去发展业务,更可行的做法是基于开源做出一些东西,让业务先往前走。因此OceanBase立项之初,除了阳振坤和他当时的直属领导,其他人对这个项目要么不关心,要么不赞成。从零开始自研分布式关系数据库并全面替换Oracle,在当时有多少人会相信这真的能做成呢?当时整个淘宝一共只有两三千人,而Oracle有十几万人,就算整个淘宝的人全部去做数据库,跟Oracle比起来也只是很小很小的一个比例。在阳振坤看来,如果一件事情几乎所有的人都认为它很重要、需要做,这件事情就已经不是创新了。当所有人都认为这件事情要做的时候,其实做这件事情的时机已经过去了一大半。作为最底层的基础软件设施,数据库需要很长时间的积累,不可能今年做,明年就能真正大规模地用起来。 虽然在2010年选择做数据库的时候,没有太多人看重和支持,对于团队来说这可能反而是一件好事。无人关注,反倒给了团队几年积累发展的时间。阳振坤不只要自研,还要把OceanBase定位成恩师王选所说的“顶天立地”的技术产品——走标准化的路,做一个通用的关系数据库产品,而不是一个仅仅在公司内部使用的产品。每个公司使用任何产品其实都只用了其中很小的一部分功能,如果只做满足公司自用需求的数据库,可能只需要投入十分之一、五分之一的人力物力时间。而要做成通用产品就意味着必须实现所有功能,这要困难得多,团队的投入、花费的精力和时间也要大好多倍。但也因为阳振坤最初的坚持,今天的OceanBase才得以走出蚂蚁金服,走进众多银行系统。不过这都是后话了。做数据库就像在黑暗中前行,守得住寂寞、担得了压力,甚至要有近乎偏执的性格才可能跨越死亡之谷,到达最终目的地。阳振坤团队中一位新人曾经向他表达过自己的困惑,当时这位新人入职三个月了,因为有太多东西要学,什么也没做出来,而跟他同时入职天猫的新员工才来了一个月,做的系统就已经在线上使用了。阳振坤当时给新人讲了一个故事,他说:“你过三年再看,没有人还记得那个同学三年前在天猫上把网页做了什么改版,可是三年以后你今天做的东西还会在生产系统中使用。”十年蛰伏,一飞冲天OceanBase的第一个客户来自淘宝收藏夹。当时的淘宝收藏夹正处于业务高速发展期,数据库的访问量飞快增长,面临着第二年服务器数量需要翻一倍甚至几倍的局面。业务方忙于寻找解决方案的时候,阳振坤主动找上门去提出了可以用OceanBase帮他们解决问题,把服务器数量降低一个数量级。四个月出Demo,八个月出试用版,一年后系统正式上线,淘宝收藏夹就这样成了第一个吃OceanBase螃蟹的业务,新数据库取得了非常好的效果。这时候是2011年,收藏夹项目成为了OceanBase第一个小小的里程碑。但在后续一年多的时间里,OceanBase团队一直在寻找更多业务,也确实有一些业务用了,却再也没有找到像淘宝收藏夹效果这么显著的业务。做数据库难度大、周期长,前几年的投入也许有那么一点点产出,但其实跟投入比几乎微不足道,团队面临的压力可想而知。数据库少不了人力投入,OceanBase团队从最早只有阳振坤一个人,后来发展到2012年已经有30多个人了。占了这么多人头,但在公司里却没有足够多、足够重要的业务,没能产生足够大的价值和效益。团队陷入了一个比较困难的时期,甚至数度濒临解散。当被问及“中间有没有想过这事如果没做成,怎么办?”,阳振坤回答得云淡风轻:“不是每件事都能做成,那太难了。如果每件事在做之前都想着它能不能做成,那最后做成的事就会很少。”在最困难也最危险的时候,团队迎来了一丝转机。2012年底,公司把OceanBase整个团队调到了支付宝。支付宝属于金融领域,面临的数据库挑战会比其他业务更大,这相当于给了OceanBase团队一次从头开始的机会。2013年夏天,支付宝也开始启动“去IOE”,并希望能够把Oracle数据库替换掉。阳振坤又一次主动出击,向当时的主管、也是现在蚂蚁金服的CTO程立自荐了OceanBase的解决方案。金融行业数据库,最怕的就是突发故障导致数据丢失,涉及到钱的事,多了少了都是不可接受的。为了解决高可用与主备库数据一致的矛盾,OceanBase将可用性做到了数据库系统内部,用一主两备或一主多备代替一主一备。主库到备库同步的时候不要求同步到每个备库,而是同步到包括主库在内的多数库(超过半数),也就是说总共三个库中如果有两个成功了,这个事务就成功了。如果任何一台机器出了问题,这个系统的可用性和数据一致性都是可以保证的。程立认可了阳振坤提出的方案,OceanBase团队开始埋头开发,第一个要攻克的目标是支付宝交易库。2014年双11,OceanBase迎来了第一次大考。大促开始前的凌晨,各个团队都在自己的作战室里热火朝天地准备。当时任蚂蚁金服董事长的彭蕾去了OceanBase团队的作战室,问大家:“有没有信心?”阳振坤跟彭蕾开了个玩笑说:“你看我们窗子都已经打开了,如果等会出问题,我们就准备从这跳下去。”在一开始的计划里,双11交易流量的1%会切给OceanBase,但因为当时的Oracle数据库系统支撑不了汹涌而来的巨大流量,最后OceanBase成功支撑了2014年双11中10%的交易流量。经过了双11的考验之后,OceanBase得到了更多的认可和支持。后来OceanBase团队获得了2015年蚂蚁金服的CEO大奖,这也是第一次由技术团队拿到这个奖。彭蕾希望借这个奖鼓励那些能够沉下心来、扎扎实实地把一项技术做好做扎实的技术人们。2015年春夏,支付宝交易库和支付库都换成了OceanBase;2016年,支付宝账务系统上线,这也标记着OceanBase真正在金融系统最核心最关键的领域站住了脚。从2017年开始,OceanBase开始走出支付宝、走出蚂蚁金服,在商业银行推广使用,最早的两家客户是浙商银行和南京银行。仅仅用了两年多的时间,OceanBase已经在人保健康险、常熟农商行、苏州银行、广东农信等数十家商业银行和保险机构上线。2017年10月,南京银行“鑫云+”互金开放平台正式发布,这是阿里云、蚂蚁金服合作整体输出的第一次尝试,通过“鑫云”+平台的建设,南京银行互金核心系统在交易处理能力、成本控制和对接效率都得到了极大的提升。南京银行传统的线下消费金融业务开展10年,余额100亿,而与互联网平台合作开展线上业务仅一年时间业务量已达到100亿。南京银行“鑫云+”平台上线后,业务快速增长,贷款交易处理能力全面升级,从原有的10万笔/天到上线后实现100万笔/天,对普惠金融起到了更有利的支撑。轻资产模式使得单账户管理成本约为传统IOE架构的1/5至1/10,从原有的3050元/账户降到了上线后的4元/账户。“鑫云+”平台的维护人员较传统银行业务系统约为1/5左右。以往合作时银行需要分别与各个互联网平台进行对接,自项目上线后,只需对接鑫云+一家平台即可实现多家互联网平台的对接,大大减少了重复建设,提高对接效率,同时也降低了中小银行以及互联网平台的对接成本。从濒临解散到浴火重生,OceanBase已经走了快十年,但在自研关系数据库这条漫漫长路上,OceanBase才仅仅走出了一小步。在阳振坤看来,OceanBase现在“开了很大的一朵花,但是结了很小的一个果”,虽然它已经向所有人证明了通用的分布式关系数据库是能够做成的,而且能真正应用在生产系统中,但今天OceanBase的应用还很有限,远远没有充分发挥它的价值。阳振坤告诉我们,OceanBase当初没有选择基于开源或已有的技术思路开发,而是选择走分布式自研这条路,虽然走得艰难,但做成之后就会成为不可替代的优势。过去这十来年正好是分布式系统发展的十来年,转型到分布式已经成为所有人都认可的一个选择。如今,以蚂蚁金服的OceanBase为代表的分布式关系数据库,不仅解决了关系数据库的扩展性问题,也极大地降低了关系数据库的成本,还提升了可用性。现在,兼容Oracle的工作是OceanBase的重中之重。OceanBase团队的目标是,用两年时间做到Oracle业务的平滑迁移,不需要修改一行代码、不需要业务做任何调整就能够将数据库迁移过来。在阳振坤看来,能够把最早的一些想法一些创新变成产品,真的是非常艰难甚至说过程中充满痛苦的一条道路。但是OceanBase做的所有事情其实还是从业务、从客户中出发,只有技术真的能够落到生产中去,落到用户中去才是真正有价值的,否则做得再好也只是一个空中楼阁。相信未来,OceanBase还会走得更快、更远。本文作者:华蒙阅读原文本文为云栖社区原创内容,未经允许不得转载。

April 17, 2019 · 1 min · jiezi

现代IM系统中的消息系统架构 - 架构篇

前言IM全称是『Instant Messaging』,中文名是即时通讯。在这个高度信息化的移动互联网时代,生活中IM类产品已经成为必备品,比较有名的如钉钉、微信、QQ等以IM为核心功能的产品。当然目前微信已经成长为一个生态型产品,但其核心功能还是IM。还有一些非以IM系统为核心的应用,最典型的如一些在线游戏、社交应用,IM也是其重要的功能模块。可以说,IM系统已经是任何一个带有社交属性的应用需要具备的基础功能,网络上对于这类系统的设计与实现的讨论也越来越多。IM系统在互联网初期即存在,其基础技术架构在这十几年的发展中更新迭代多次,从早期的CS、P2P架构,到现在后台已经演变为一个复杂的分布式系统,涉及移动端、网络通信、协议、安全、存储和搜索等技术的方方面面。IM系统中最核心的部分是消息系统,消息系统中最核心的功能是消息的同步、存储和检索:消息的同步:将消息完整的、快速的从发送方传递到接收方,就是消息的同步。消息同步系统最重要的衡量指标就是消息传递的实时性、完整性以及能支撑的消息规模。从功能上来说,一般至少要支持在线和离线推送,高级的IM系统还支持『多端同步』。消息的存储:消息存储即消息的持久化保存,传统消息系统通常只能支持消息在接收端的本地存储,数据基本不具备可靠性。现代消息系统能支持消息在服务端的在线存储,功能上对应的就是『消息漫游』,消息漫游的好处是可以实现账号在任意端登陆查看所有历史消息。消息的检索:消息一般是文本,所以支持全文检索也是必备的能力之一。传统消息系统通常来说也是只能支持消息的本地检索,基于本地存储的消息数据来构建。而现在消息系统在能支持消息的在线存储后,也具备了消息的『在线检索』能力。本篇文章内容主要涉及IM系统中的消息系统架构,会介绍一种基于阿里云表格存储Tablestore的Timeline模型构建的消息系统。基于Tablestore Timeline构建的现代消息系统,能够同时支持消息系统的众多高级特性,包括『多端同步』、『消息漫游』和『在线检索』。在性能和规模上,能够做到全量消息云端存储和索引,百万TPS写入以及毫秒级延迟的消息同步和检索能力。之后我们会继续发表两篇文章,来更详细介绍Tablestore Timeline模型概念及使用:模型篇:详细介绍Tablestore Timeline模型的基本概念和基础数据结构,并结合IM系统进行基本的建模。实现篇:会基于Tablestore Timeline实现一个具备『多端同步』、『消息漫游』和『在线检索』这些高级功能的简易IM系统,并共享我们的源代码。传统架构 vs 现代架构传统架构下,消息是先同步后存储。对于在线的用户,消息会直接实时同步到在线的接收方,消息同步成功后,并不会在服务端持久化。而对于离线的用户或者消息无法实时同步成功时,消息会持久化到离线库,当接收方重新连接后,会从离线库拉取所有未读消息。当离线库中的消息成功同步到接收方后,消息会从离线库中删除。传统的消息系统,服务端的主要工作是维护发送方和接收方的连接状态,并提供在线消息同步和离线消息缓存的能力,保证消息一定能够从发送方传递到接收方。服务端不会对消息进行持久化,所以也无法支持消息漫游。消息的持久化存储及索引同样只能在接收端本地实现,数据可靠性极低。现代架构下,消息是先存储后同步。先存储后同步的好处是,如果接收方确认接收到了消息,那这条消息一定是已经在云端保存了。并且消息会有两个库来保存,一个是消息存储库,用于全量保存所有会话的消息,主要用于支持消息漫游。另一个是消息同步库,主要用于接收方的多端同步。消息从发送方发出后,经过服务端转发,服务端会先将消息保存到消息存储库,后保存到消息同步库。完成消息的持久化保存后,对于在线的接收方,会直接选择在线推送。但在线推送并不是一个必须路径,只是一个更优的消息传递路径。对于在线推送失败或者离线的接收方,会有另外一个统一的消息同步方式。接收方会主动的向服务端拉取所有未同步消息,但接收方何时来同步以及会在哪些端来同步消息对服务端来说是未知的,所以要求服务端必须保存所有需要同步到接收方的消息,这是消息同步库的主要作用。对于新的同步设备,会有消息漫游的需求,这是消息存储库的主要作用,在消息存储库中,可以拉取任意会话的全量历史消息。消息检索的实现依赖于对消息存储库内消息的索引,通常是一个近实时(NRT,near real time)的索引构建过程,这个索引同样是在线的。以上就是传统架构和现代架构的一个简单的对比,现代架构上整个消息的同步、存储和索引流程,并没有变复杂太多。现代架构的实现本质上是把传统架构内本地存储和索引都搬到云上,最大挑战是需要集中管理全量消息的存储和索引,带来的好处是能实现多端同步、消息漫游以及在线检索。可以看到现代架构中最核心的就是两个消息库『消息同步库』和『消息存储库』,以及对『消息存储库』的『消息索引』的实现,接下来我们逐步拆解这几个核心的设计和实现。基础模型在深入讲解消息系统的设计和实现之前,需要对消息系统内的几个基本概念和基础模型有一个理解。网上分析的很多的不同类型的消息系统实现,实现差异上主要在消息同步和存储的方案上,在消息的数据模型上其实有很大的共性。围绕数据同步模型的讨论主要在『读扩散』、『写扩散』和『混合模式』这三种方案,目前还没有更多的选择。而对于数据模型的抽象,还没有一个标准的定义。本章节会介绍下表格存储Tablestore提出的Timeline模型,这是一个对消息系统内消息模型的一个抽象,能简化和更好的让开发者理解消息系统内的消息同步和存储模型,基于此模型我们会再深入探讨消息的同步和存储的选择和实现。Timeline模型Timeline是一个对消息抽象的逻辑模型,该模型会帮助我们简化对消息同步和存储模型的理解,而消息同步库和存储库的设计和实现也是围绕Timeline的特性和需求来展开。如图是Timeline模型的一个抽象表述,Timeline可以简单理解为是一个消息队列,但这个消息队列有如下特性:每条消息对应一个顺序ID:每个消息拥有一个唯一的顺序ID(SequenceId),队列消息按SequenceId排序。新消息写入能自动分配递增的顺序ID,保证永远插入队尾:Timeline中是根据同步位点也就是顺序ID来同步消息,所以需要保证新写入的消息数据的顺序ID绝对不能比已同步的消息的顺序ID还小,否则会导致数据漏同步,所以需要支持对新写入的数据自动分配比当前已存储的所有消息的顺序ID更大的顺序ID。新消息写入也能自定义顺序ID,满足自定义排序需求:上面提到的自动分配顺序ID,主要是为了满足消息同步的需求,消息同步要求消息是根据『已同步』或是『已写入』的顺序来排序。而消息的存储,通常要求消息能根据会话顺序来排序,会话顺序通常由端的会话来决定,而不是服务端的同步顺序来定,这是两种顺序要求。支持根据顺序ID的随机定位:可根据SequenceId随机定位到Timeline中的某个位置,从这个位置开始正序或逆序的读取消息,也可支持读取指定顺序ID的某条消息。支持对消息的自定义索引:消息体内数据根据业务不同会包含不同的字段,Timeline需要支持对不同字段的自定义索引,来支持对消息内容的全文索引,或者是任意字段的灵活条件组合查询。消息同步可以基于Timeline很简单的实现,图中的例子中,消息发送方是A,消息接收方是B,同时B存在多个接收端,分别是B1、B2和B3。A向B发送消息,消息需要同步到B的多个端,待同步的消息通过一个Timeline来进行交换。A向B发送的所有消息,都会保存在这个Timeline中,B的每个接收端都是独立的从这个Timeline中拉取消息。每个接收端同步完毕后,都会在本地记录下最新同步到的消息的SequenceId,即最新的一个位点,作为下次消息同步的起始位点。服务端不会保存各个端的同步状态,各个端均可以在任意时间从任意点开始拉取消息。消息存储也是基于Timeline实现,和消息同步唯一的区别是,消息存储要求服务端能够对Timeline内的所有数据进行持久化,并且消息采用会话顺序来保存,需要自定义顺序ID。消息检索基于Timeline提供的消息索引来实现,能支持比较灵活的多字段索引,根据业务的不同可有自由度较高的定制。消息存储模型如图是基于Timeline的消息存储模型,消息存储要求每个会话都对应一个独立的Timeline。如图例子所示,A与B/C/D/E/F均发生了会话,每个会话对应一个独立的Timeline,每个Timeline内存有这个会话中的所有消息,消息根据会话顺序排序,服务端会对每个Timeline进行持久化存储,也就拥有了消息漫游的能力。消息同步模型消息同步模型会比消息存储模型稍复杂一些,消息的同步一般有读扩散(也叫拉模式)和写扩散(也叫推模式)两种不同的方式,分别对应不同的Timeline物理模型。如图是读扩散和写扩散两种不同同步模式下对应的不同的Timeline模型,按图中的示例,A作为消息接收者,其与B/C/D/E/F发生了会话,每个会话中的新的消息都需要同步到A的某个端,看下读扩散和写扩散两种模式下消息如何做同步。读扩散:消息存储模型中,每个会话的Timeline中保存了这个会话的全量消息。读扩散的消息同步模式下,每个会话中产生的新的消息,只需要写一次到其用于存储的Timeline中,接收端从这个Timeline中拉取新的消息。优点是消息只需要写一次,相比写扩散的模式,能够大大降低消息写入次数,特别是在群消息这种场景下。但其缺点也比较明显,接收端去同步消息的逻辑会相对复杂和低效。接收端需要对每个会话都拉取一次才能获取全部消息,读被大大的放大,并且会产生很多无效的读,因为并不是每个会话都会有新消息产生。写扩散:写扩散的消息同步模式,需要有一个额外的Timeline来专门用于消息同步,通常是每个接收端都会拥有一个独立的同步Timeline(或者叫收件箱),用于存放需要向这个接收端同步的所有消息。每个会话中的消息,会产生多次写,除了写入用于消息存储的会话Timeline,还需要写入需要同步到的接收端的同步Timeline。在个人与个人的会话中,消息会被额外写两次,除了写入这个会话的存储Timeline,还需要写入参与这个会话的两个接收者的同步Timeline。而在群这个场景下,写入会被更加的放大,如果这个群拥有N个参与者,那每条消息都需要额外的写N次。写扩散同步模式的优点是,在接收端消息同步逻辑会非常简单,只需要从其同步Timeline中读取一次即可,大大降低了消息同步所需的读的压力。其缺点就是消息写入会被放大,特别是针对群这种场景。Timeline模型不会对选择读扩散还是写扩散做约束,而是能同时支持两种模式,因为本质上两种模式的逻辑数据模型并无差别,只是消息数据是用一个Timeline来支持多端读还是复制到多个Timeline来支持多端读的问题。针对IM这种应用场景,消息系统通常会选择写扩散这种消息同步模式。IM场景下,一条消息只会产生一次,但是会被读取多次,是典型的读多写少的场景,消息的读写比例大概是10:1。若使用读扩散同步模式,整个系统的读写比例会被放大到100:1。一个优化的好的系统,必须从设计上去平衡这种读写压力,避免读或写任意一维触碰到天花板。所以IM系统这类场景下,通常会应用写扩散这种同步模式,来平衡读和写,将100:1的读写比例平衡到30:30。当然写扩散这种同步模式,还需要处理一些极端场景,例如万人大群。针对这种极端写扩散的场景,会退化到使用读扩散。一个简单的IM系统,通常会在产品层面限制这种大群的存在,而对于一个高级的IM系统,会采用读写扩散混合的同步模式,来满足这类产品的需求。采用混合模式,会根据数据的不同类型和不同的读写负载,来决定用写扩散还是读扩散。典型架构设计如图是一个典型的消息系统架构,架构中包含几个重要组件:端:作为消息的发送和接收端,通过连接消息服务器来发送和接收消息。消息服务器:一组无状态的服务器,可水平扩展,处理消息的发送和接收请求,连接后端消息系统。消息队列:新写入消息的缓冲队列,消息系统的前置消息存储,用于削峰填谷以及异步消费。消息处理:一组无状态的消费处理服务器,用于异步消费消息队列中的消息数据,处理消息的持久化和写扩散同步。消息存储和索引库:持久化存储消息,每个会话对应一个Timeline进行消息存储,存储的消息建立索引来实现消息检索。消息同步库:写扩散形式同步消息,每个用户的收件箱对应一个Timeline,同步库内消息不需要永久保存,通常对消息设定一个生命周期。新消息会由端发出,通常消息体中会携带消息ID(用于去重)、逻辑时间戳(用于排序)、消息类型(控制消息、图片消息或者文本消息等)、消息体等内容。消息会先写入消息队列,作为底层存储的一个临时缓冲区。消息队列中的消息会由消息处理服务器消费,可以允许乱序消费。消息处理服务器对消息先存储后同步,先写入发件箱Timeline(存储库),后写扩散至各个接收端的收件箱(同步库)。消息数据写入存储库后,会被近实时的构建索引,索引包括文本消息的全文索引以及多字段索引(发送方、消息类型等)。对于在线的设备,可以由消息服务器主动推送至在线设备端。对于离线设备,登录后会主动向服务端同步消息。每个设备会在本地保留有最新一条消息的顺序ID,向服务端同步该顺序ID后的所有消息。总结本篇文章主要介绍了现代IM系统中消息系统所需要具备的能力,对比了传统架构和现代架构。为方便接下来的深入探讨,介绍了表格存储Tablestore推出的Timeline模型,以及在IM系统中消息存储和消息同步模型的基本概念和策略,最后介绍了一个典型的架构设计。本文作者:木洛阅读原文本文为云栖社区原创内容,未经允许不得转载。

April 16, 2019 · 1 min · jiezi

阿里云数据库自研产品亮相国际顶级会议ICDE 推动云原生数据库成为行业标准

4月9日,澳门当地时间下午4:00-5:30,阿里云在ICDE 2019举办了主题为“云时代的数据库”的专场分享研讨会。本次专场研讨会由阿里巴巴集团副总裁、高级研究员,阿里云智能数据库产品事业部负责人李飞飞(花名:飞刀)主持,五位学术界知名学者和教授受邀参加作为Panel Discussion的嘉宾,与现场近百位与会者进行了深入交流讨论。这五位教授分别是:Anastasia Aliamaki,Professor and ACM Fellow, EPFL;Ihab Ilyas, Professor and ACM Distinguished Scientist, Vice Chair of ACM SIGMOD, University of Waterloo;Guoliang Li, Professor, Tsinghua University;C Mohan,IBM Fellow,IEEE&ACM Fellow,IBM; Xiaofang Zhou, Professor & IEEE Fellow, University of Queensland;整场分享讨论会分为两部分。第一部分先由来自阿里巴巴集团、阿里云智能数据库产品事业部的吕漫漪、林亮、黄贵、乔红麟技术专家们分别介绍了阿里巴巴在POLARDB for MySQL, POLARDB X, AnalyticDB, 以及智能化自治数据库平台SDDP(Self-Driving Database Platform)等产品和技术的进展,以及如何依靠创新来帮助企业解决传统数据库业务场景中在数据处理方面面临的挑战,体现出阿里云智能数据库的技术领先性,以及品牌和文化,目前阿里云数据库在全球云数据市场上位列前三。第二部分由几位专家分别就云时代的数据库趋势和挑战发表了自己的见解,然后就与会学者关心的问题进行了深入探讨。其中,C Mohan博士提出,云时代下Serverless允许用户实现应用无需考虑软硬件配置,并且通过PaaS实现自动扩展,对数据库来说,自身健壮性是基础要求,另外还需要加强分布式负载的处理能力。目前面临一些挑战,例如公有云用户是一个私有环境,混合云方面还需要优秀的分布式OLTP DBMS, 内存/存储架构上还有很多工作可以做。除此之外,数据安全、数据管理方面都是需要考虑的问题。数据显示,中国84%以上的企业表示愿意接受云技术。针对目前面临的挑战,Anastasia Aliamaki 教授指出,一是数据多样性(关系型数据,非关系型数据)对于数据库处理数据是一个巨大挑战,需要构建一个智能的数据库来处理各种各样的负载,需要扩展SQL接口,code-generation提供了运行时构建相应底层数据的访问路径;二是 data cleaning是极其消耗资源的,包括数据从传统数据库迁移到云数据库的迁移工具(用户可以不关心如何迁移的细节问题)。对于用户来说,如果能让用户上述两点都能做到无感知应用,这无疑是云数据库的最大亮点。周晓方教授认为,从传统数据库迁移到云数据库是一个系统工程。为了提升用户体验的满意度,云数据库努力解决高并发、扩展等问题,用户从传统数据库迁移到云数据库不仅仅是一次迁移,也是一次自我调优的过程,可以构建生态系统,从不同的领域开展深入研究。Ihab Ilyas教授分享了在Data Cleaning and Integration to cloud领域的洞见和成果。他特别指出,迁移到云数据库问题不在云本身,用户通常选择他熟悉的产品。云数据库必须了解客户需求,解决客户问题。他说:“对于大数据工程师来说,算法的实现对他们不是噩梦,Hadoop版本却成为他们的噩梦。我们发现迁移这个事情已经在发生,但是我们需要更多关注这个过程本身,并且对过程敏感,能够带给用户无痛感的迁移。”李国良教授认为,云数据库最大的特点是不需要维护数据库,可以节约DBA成本,但是数据库是比操作系统还复杂的系统,需要迁移数据库设计的生态系统,并构建相应的APP。小公司业务应用简单容易上云,大公司因为业务太过复杂不太容易上云,云厂商需要解决大公司的应用迁移问题。最后,数据库领域的专家学者们强调可以借鉴云和大数据生态的演进发展,逐步把数据库技术带入机器学习中而不是强求打造一个“全能的”数据库。最后几位教授也对阿里巴巴在此领域的继续贡献充满期盼。本文作者:桐碧2018阅读原文本文为云栖社区原创内容,未经允许不得转载。

April 16, 2019 · 1 min · jiezi