利用 Map-Reduce 从文件中找到出现频率最高的 10 个 URL(2021 VLDB Summer School Lab0)

article/2025/10/29 8:40:36

这篇博文主要是对 2021 VLDB Summer School Lab0 的一个总结

这个lab与MIT 6.824 的 lab1 相似,个人感觉比MIT 6.824 的 lab1 要稍微简单些,更容易上手。通过这个lab,可以学习到一些 Golang 的基础知识并对分布式系统有一个基础的了解,我做下来感觉文档写得十分完善,包括需要的一些前置知识都说得很清楚,同时还提供了一些学习资源,强烈推荐分布式系统的初学者做一下这个lab,传送门:https://github.com/tidb-incubator/vldbss-2021/tree/master/lab0

Map-Reduce简介

我之前对Map-Reduce只是简单听说过,没有仔细了解,我首先看了lab里推荐的 MIT 6.824 课程,不过一节课1个多小时,感觉节奏稍微有点慢,我就直接找的原始论文《MapReduce: simplified data processing on large clusters》 对Map-Reduce进行了一个简要地学习。

简单来说,Map-Reduce是一个分布式的用来处理大规模数据的High-Level框架,之所以称之为High-Level是因为在设计它时就是为了让它能够处理大部分分布式数据处理任务,即适用范围要广,所以它的抽象程度会比较高。

整个Map-Reduce框架的主要组成部分如下图所示:

 执行流程大致为:

  • 读入输入文件
  • Master分配分布式集群中的worker(一台可以用于计算的服务器)对输入数据执行map操作,并将执行结果写入该worker的本地磁盘
  • map操作的结果成功写入磁盘后会通知Master,此时Master会分配一个reduce任务给一台空闲worker 同时告诉它去哪可以取到map操作的结果,这时这台worker会通过RPC(Remote Procedure Call,远程过程调用)取到map操作的结果,然后以此作为输入执行reduce操作,最后将reduce操作的结果输出为一个单独的文件,注意此时与map操作结果直接写入worker本地不同,reduce操作结果的输出目的地一般是GFS等分布式文件系统或者是作为下一轮Map-Reduce的输入

在这整个过程中,只有Map操作和Reduce操作是由用户自己编写,其余的均由框架完成。

也就是说,我们只关心Map函数和Reduce函数应该完成哪些任务,就可以完成各种各样的分布式数据处理任务,使得分布式处理任务的编码成本得以降低,这也是Map-Reduce框架的主要意义所在。

Lab0 任务一:完成 Map-Reduce 框架

这次lab设计得对初学者十分友好,lab中提供的源码对Map-Reduce框架已经完成了很大一部分,包括Map阶段的代码都是完整的,所以初学者经过简单地学习go语言之后,可以通过阅读框架中已经写好的代码进行快速地上手。

从最简单的的开始,我们首先对Reduce阶段进行实现。

Reduce阶段需要拿到对应的map操作的执行结果,然后以此作为输入执行reduce操作,最后将执行结果输出为一个文件即可,具体代码如下:

				// YOUR CODE HERE :)// hint: don't encode results returned by ReduceF, and just output// them into the destination file directly so that users can get// results formatted as what they want.if t.phase != reducePhase {panic("unknown task phase")}reduceRes := make(map[string][]string)for i := 0; i < t.nMap; i++ {//通过文件名规则拿到对应map的结果mappedFileName := reduceName(t.dataDir, t.jobName, i, t.taskNumber)mappedFile, err := os.Open(mappedFileName)if err != nil {log.Fatalln("open mapped file error: ", mappedFileName, " error: ", err)}dec := json.NewDecoder(mappedFile)for {var kv KeyValueif err := dec.Decode(&kv); err != nil {break //EOF}if _, exist := reduceRes[kv.Key]; !exist {reduceRes[kv.Key] = make([]string, 0)}reduceRes[kv.Key] = append(reduceRes[kv.Key], kv.Value)}SafeClose(mappedFile, nil)}fs, bs := CreateFileAndBuf(mergeName(t.dataDir, t.jobName, t.taskNumber))for k, v := range reduceRes {//输出Reduce结果WriteToBuf(bs, t.reduceF(k, v))}SafeClose(fs, bs)

观察发现,Map-Reduce 框架需要补充的部分就还剩:Master分发的Map任务都执行完毕之后的执行逻辑

分析得知,map任务都执行完毕之后需要接着分发Reduce任务,对着上面已经写好的Map任务分发逻辑,可以照猫画虎地对Reduce任务分发逻辑进行编写:

	// reduce phase// YOUR CODE HERE :DreduceTasks := make([]*task, 0, nReduce)for i := 0; i < nReduce; i++ {t := &task{dataDir:    dataDir,jobName:    jobName,phase:      reducePhase,taskNumber: i,nMap:       nMap,reduceF:    reduceF,}t.wg.Add(1)reduceTasks = append(reduceTasks, t)go func() { c.taskCh <- t }()}for _, t := range reduceTasks {t.wg.Wait()}

以终为始,我们可以通过查看测试函数是如何进行测试的来分析Reduce操作都结束之后是否还需要进行其他操作:

通过分析测试函数(位于urltop10_test.go中)可以发现,测试的逻辑是首先通过Submit函数的返回拿到一个channel,再通过这个channel拿到结果文件,最后通过将这个结果文件和正确结果进行对比从而完成测试,这里需要注意的是最后的输出文件列表最终应该只有一个文件,而每一个Reduce操作都会输出一个结果文件,也就是说最后一轮Reduce操作应该只有唯一的一个worker执行。

分析下来得知,最后我们只需要将Reduce操作的结果放入对应的channel,以便让测试函数拿到这个结果即可:

	results := make([]string,0,nReduce)for i := 0; i < nReduce; i++ {results = append(results, mergeName(dataDir, jobName, i))}notify <- results

 至此,我们就完成了 Map-Reduce 框架。

下面可以通过lab中的make test_example来测试我们的编码是否正确,由于我是直接在我的PC上跑,有可能会出发超时错误,所以我更改了一下test_example脚本,放宽超时时间到一个小时,更改后的脚本如下:

test_example:go test -v -timeout 60m -run=TestExampleURLTop

执行

make test_example > ./log/test_example.log

进行测试,同时将测试结果重定向输出到test_example.log,测试结果如下:

go test -v -timeout 60m -run=TestExampleURLTop
=== RUN   TestExampleURLTop
Case0 PASS, dataSize=1MB, nMapFiles=5, cost=54.1068ms
Case1 PASS, dataSize=1MB, nMapFiles=5, cost=35.8471ms
Case2 PASS, dataSize=1MB, nMapFiles=5, cost=34.1654ms
Case3 PASS, dataSize=1MB, nMapFiles=5, cost=43.7147ms
Case4 PASS, dataSize=1MB, nMapFiles=5, cost=79.54ms
Case5 PASS, dataSize=1MB, nMapFiles=5, cost=49.3617ms
Case6 PASS, dataSize=1MB, nMapFiles=5, cost=46.5659ms
Case7 PASS, dataSize=1MB, nMapFiles=5, cost=50.0676ms
Case8 PASS, dataSize=1MB, nMapFiles=5, cost=48.8755ms
Case9 PASS, dataSize=1MB, nMapFiles=5, cost=41.0224ms
Case10 PASS, dataSize=1MB, nMapFiles=5, cost=38.5016ms
Case0 PASS, dataSize=10MB, nMapFiles=10, cost=320.2324ms
Case1 PASS, dataSize=10MB, nMapFiles=10, cost=167.8428ms
Case2 PASS, dataSize=10MB, nMapFiles=10, cost=120.667ms
Case3 PASS, dataSize=10MB, nMapFiles=10, cost=119.6882ms
Case4 PASS, dataSize=10MB, nMapFiles=10, cost=641.7379ms
Case5 PASS, dataSize=10MB, nMapFiles=10, cost=321.3038ms
Case6 PASS, dataSize=10MB, nMapFiles=10, cost=301.4055ms
Case7 PASS, dataSize=10MB, nMapFiles=10, cost=364.9047ms
Case8 PASS, dataSize=10MB, nMapFiles=10, cost=223.7273ms
Case9 PASS, dataSize=10MB, nMapFiles=10, cost=178.8921ms
Case10 PASS, dataSize=10MB, nMapFiles=10, cost=158.2368ms
Case0 PASS, dataSize=100MB, nMapFiles=20, cost=3.1390011s
Case1 PASS, dataSize=100MB, nMapFiles=20, cost=1.3893513s
Case2 PASS, dataSize=100MB, nMapFiles=20, cost=954.1715ms
Case3 PASS, dataSize=100MB, nMapFiles=20, cost=2.4240299s
Case4 PASS, dataSize=100MB, nMapFiles=20, cost=2.7511003s
Case5 PASS, dataSize=100MB, nMapFiles=20, cost=3.6331775s
Case6 PASS, dataSize=100MB, nMapFiles=20, cost=3.2044724s
Case7 PASS, dataSize=100MB, nMapFiles=20, cost=3.9406203s
Case8 PASS, dataSize=100MB, nMapFiles=20, cost=2.0936492s
Case9 PASS, dataSize=100MB, nMapFiles=20, cost=1.5503635s
Case10 PASS, dataSize=100MB, nMapFiles=20, cost=1.2076629s
Case0 PASS, dataSize=500MB, nMapFiles=40, cost=25.4456317s
Case1 PASS, dataSize=500MB, nMapFiles=40, cost=14.8783234s
Case2 PASS, dataSize=500MB, nMapFiles=40, cost=10.4408874s
Case3 PASS, dataSize=500MB, nMapFiles=40, cost=10.4135559s
Case4 PASS, dataSize=500MB, nMapFiles=40, cost=10.8568517s
Case5 PASS, dataSize=500MB, nMapFiles=40, cost=21.310093s
Case6 PASS, dataSize=500MB, nMapFiles=40, cost=18.2229292s
Case7 PASS, dataSize=500MB, nMapFiles=40, cost=18.1044385s
Case8 PASS, dataSize=500MB, nMapFiles=40, cost=14.2397967s
Case9 PASS, dataSize=500MB, nMapFiles=40, cost=12.504795s
Case10 PASS, dataSize=500MB, nMapFiles=40, cost=14.0792216s
Case0 PASS, dataSize=1GB, nMapFiles=60, cost=48.314779s
Case1 PASS, dataSize=1GB, nMapFiles=60, cost=29.9605215s
Case2 PASS, dataSize=1GB, nMapFiles=60, cost=21.816549s
Case3 PASS, dataSize=1GB, nMapFiles=60, cost=20.0377209s
Case4 PASS, dataSize=1GB, nMapFiles=60, cost=20.6936616s
Case5 PASS, dataSize=1GB, nMapFiles=60, cost=47.7212088s
Case6 PASS, dataSize=1GB, nMapFiles=60, cost=41.5137968s
Case7 PASS, dataSize=1GB, nMapFiles=60, cost=44.1715308s
Case8 PASS, dataSize=1GB, nMapFiles=60, cost=32.9036035s
Case9 PASS, dataSize=1GB, nMapFiles=60, cost=24.7098543s
Case10 PASS, dataSize=1GB, nMapFiles=60, cost=2m32.8035366s
--- PASS: TestExampleURLTop (881.19s)
PASS
ok  	talent	881.572s

测试通过,总耗时为:881.572s

至此lab0的任务一完成

Lab0 任务二:基于 Map-Reduce 框架编写 Map-Reduce 函数

lab在urltop10_example.go中提供了 Map-Reduce 函数的一种实现供我们参考:

func ExampleURLTop10(nWorkers int) RoundsArgs {var args RoundsArgs// round 1: do url countargs = append(args, RoundArgs{MapFunc:    ExampleURLCountMap,ReduceFunc: ExampleURLCountReduce,NReduce:    nWorkers,})// round 2: sort and get the 10 most frequent URLsargs = append(args, RoundArgs{MapFunc:    ExampleURLTop10Map,ReduceFunc: ExampleURLTop10Reduce,NReduce:    1,})return args
}// ExampleURLCountMap is the map function in the first round
func ExampleURLCountMap(filename string, contents string) []KeyValue {lines := strings.Split(contents, "\n")kvs := make([]KeyValue, 0, len(lines))for _, l := range lines {l = strings.TrimSpace(l)if len(l) == 0 {continue}kvs = append(kvs, KeyValue{Key: l})}return kvs
}// ExampleURLCountReduce is the reduce function in the first round
func ExampleURLCountReduce(key string, values []string) string {return fmt.Sprintf("%s %s\n", key, strconv.Itoa(len(values)))
}// ExampleURLTop10Map is the map function in the second round
func ExampleURLTop10Map(filename string, contents string) []KeyValue {lines := strings.Split(contents, "\n")kvs := make([]KeyValue, 0, len(lines))for _, l := range lines {kvs = append(kvs, KeyValue{"", l})}return kvs
}// ExampleURLTop10Reduce is the reduce function in the second round
func ExampleURLTop10Reduce(key string, values []string) string {cnts := make(map[string]int, len(values))for _, v := range values {v := strings.TrimSpace(v)if len(v) == 0 {continue}tmp := strings.Split(v, " ")n, err := strconv.Atoi(tmp[1])if err != nil {panic(err)}cnts[tmp[0]] = n}us, cs := TopN(cnts, 10)buf := new(bytes.Buffer)for i := range us {fmt.Fprintf(buf, "%s: %d\n", us[i], cs[i])}return buf.String()
}

示例中的Map-Reduce函数共两轮,第一轮作计数,第二轮作排序同时作Top10的过滤

通过分析,我认为实现找到 10 个出现频率最高的 URL 这个需求还是逃不开计数、排序、Top10过滤这三个步骤。

虽然总体思路还是和示例函数一样,但是我在实现细节上作了一些优化:

  1. 在第一轮Map时合并相同的key(即在做分词的同时再做计数),以此减少传输I/O
  2. 在第一轮Reduce时,不再简单地直接进行输出,而是对特定的key的频率做累加求和
  3. 在第二轮Map时,做排序和Top10过滤,只输出本次Map频率前十的URL(不再输出所有URL),以此减少传输I/O

第二轮Reduce与示例函数一致,做最终的Top10查找

整体代码如下:

// K Top K
const K = 10// URLTop10 .
func URLTop10(nWorkers int) RoundsArgs {// YOUR CODE HERE :)// And don't forget to document your idea.var args RoundsArgs// round 1: both map phase and reduce phase do the url countargs = append(args, RoundArgs{MapFunc:    URLTop10CountMap,ReduceFunc: URLTop10CountReduce,NReduce:    nWorkers,})// round 2: both map phase and reduce do sort and topK filterargs = append(args, RoundArgs{MapFunc:    URLTop10SortFilterMap,ReduceFunc: URLTop10SortFilterReduce,NReduce:    1,})return args
}// URLTop10CountMap count url and combine same key to reduce IO
func URLTop10CountMap(filename string, contents string) []KeyValue {lines := strings.Split(contents, "\n")kvMap := make(map[string]int)for _, url := range lines {url = strings.TrimSpace(url)if len(url) == 0 {continue}if _, exist := kvMap[url]; !exist {kvMap[url] = 0}kvMap[url] = kvMap[url] + 1}kvs := make([]KeyValue, 0)for k, v := range kvMap {kvs = append(kvs,KeyValue{Key: k,Value: strconv.Itoa(v)})}return kvs
}// URLTop10CountReduce calculate key's total count
func URLTop10CountReduce(key string, values []string) string {count := 0for _, v := range values {vInt, err := strconv.Atoi(v)if err != nil{panic(err)}count += vInt}return fmt.Sprintf("%s: %d\n", key, count)
}// URLTop10SortFilterMap do sort and topK filter
func URLTop10SortFilterMap(filename string, contents string) []KeyValue {lines := strings.Split(contents, "\n")cnts := make(map[string]int)for _, v := range lines {v := strings.TrimSpace(v)if len(v) == 0 {continue}tmp := strings.Split(v, ": ")n, err := strconv.Atoi(tmp[1])if err != nil {panic(err)}cnts[tmp[0]] = n}us, cs := TopN(cnts, K)kvs := make([]KeyValue, 0, K)for i := range us {kvs = append(kvs,KeyValue{Key:"",Value: fmt.Sprintf("%s: %d",us[i],cs[i])})}return kvs
}// URLTop10SortFilterReduce do sort and topK filter
func URLTop10SortFilterReduce(key string, values []string) string {kvMap := make(map[string]int, len(values))for _, value := range values {tmp := strings.Split(value, ": ")url := strings.TrimSpace(tmp[0])if len(url) == 0 {continue}n, err := strconv.Atoi(tmp[1])if err != nil {panic(err)}if _, exist := kvMap[url]; !exist {kvMap[url] = 0}kvMap[url] = kvMap[url] + n}us, cs := TopN(kvMap, K)buf := new(bytes.Buffer)for i := range us {fmt.Fprintf(buf, "%s: %d\n", us[i], cs[i])}return buf.String()
}

由于Map和Reduce函数都不是I/O密集型,所以第一轮NReduce参数仍使用nWorkers

通过上面对测试函数的分析(最终输出结果的文件列表应该只有一个文件),第二轮NReduce参数保持为1

执行

make test_homework > ./log/test_homework.log

进行测试,同时将测试结果重定向输出到test_homework.log,测试结果如下:

go test -v -timeout 60m -run=TestURLTop
=== RUN   TestURLTop
Case0 PASS, dataSize=1MB, nMapFiles=5, cost=25.0578ms
Case1 PASS, dataSize=1MB, nMapFiles=5, cost=29.6926ms
Case2 PASS, dataSize=1MB, nMapFiles=5, cost=282.7606ms
Case3 PASS, dataSize=1MB, nMapFiles=5, cost=77.0294ms
Case4 PASS, dataSize=1MB, nMapFiles=5, cost=38.2195ms
Case5 PASS, dataSize=1MB, nMapFiles=5, cost=185.0714ms
Case6 PASS, dataSize=1MB, nMapFiles=5, cost=30.1719ms
Case7 PASS, dataSize=1MB, nMapFiles=5, cost=30.1969ms
Case8 PASS, dataSize=1MB, nMapFiles=5, cost=94.7232ms
Case9 PASS, dataSize=1MB, nMapFiles=5, cost=28.062ms
Case10 PASS, dataSize=1MB, nMapFiles=5, cost=20.1835ms
Case0 PASS, dataSize=10MB, nMapFiles=10, cost=40.7678ms
Case1 PASS, dataSize=10MB, nMapFiles=10, cost=47.6344ms
Case2 PASS, dataSize=10MB, nMapFiles=10, cost=54.7339ms
Case3 PASS, dataSize=10MB, nMapFiles=10, cost=77.6767ms
Case4 PASS, dataSize=10MB, nMapFiles=10, cost=261.5726ms
Case5 PASS, dataSize=10MB, nMapFiles=10, cost=310.2633ms
Case6 PASS, dataSize=10MB, nMapFiles=10, cost=44.0939ms
Case7 PASS, dataSize=10MB, nMapFiles=10, cost=50.4649ms
Case8 PASS, dataSize=10MB, nMapFiles=10, cost=50.4096ms
Case9 PASS, dataSize=10MB, nMapFiles=10, cost=58.3175ms
Case10 PASS, dataSize=10MB, nMapFiles=10, cost=45.2759ms
Case0 PASS, dataSize=100MB, nMapFiles=20, cost=146.0478ms
Case1 PASS, dataSize=100MB, nMapFiles=20, cost=544.0832ms
Case2 PASS, dataSize=100MB, nMapFiles=20, cost=235.3012ms
Case3 PASS, dataSize=100MB, nMapFiles=20, cost=1.4182167s
Case4 PASS, dataSize=100MB, nMapFiles=20, cost=1.6650558s
Case5 PASS, dataSize=100MB, nMapFiles=20, cost=315.7017ms
Case6 PASS, dataSize=100MB, nMapFiles=20, cost=153.0375ms
Case7 PASS, dataSize=100MB, nMapFiles=20, cost=161.2142ms
Case8 PASS, dataSize=100MB, nMapFiles=20, cost=3.6473142s
Case9 PASS, dataSize=100MB, nMapFiles=20, cost=201.0136ms
Case10 PASS, dataSize=100MB, nMapFiles=20, cost=382.0689ms
Case0 PASS, dataSize=500MB, nMapFiles=40, cost=3.9562808s
Case1 PASS, dataSize=500MB, nMapFiles=40, cost=8.7393114s
Case2 PASS, dataSize=500MB, nMapFiles=40, cost=2.5093273s
Case3 PASS, dataSize=500MB, nMapFiles=40, cost=4.3728053s
Case4 PASS, dataSize=500MB, nMapFiles=40, cost=7.8807145s
Case5 PASS, dataSize=500MB, nMapFiles=40, cost=4.0481183s
Case6 PASS, dataSize=500MB, nMapFiles=40, cost=5.6082772s
Case7 PASS, dataSize=500MB, nMapFiles=40, cost=3.2234075s
Case8 PASS, dataSize=500MB, nMapFiles=40, cost=2.1543608s
Case9 PASS, dataSize=500MB, nMapFiles=40, cost=3.4617415s
Case10 PASS, dataSize=500MB, nMapFiles=40, cost=534.848ms
Case0 PASS, dataSize=1GB, nMapFiles=60, cost=9.7468331s
Case1 PASS, dataSize=1GB, nMapFiles=60, cost=8.9736291s
Case2 PASS, dataSize=1GB, nMapFiles=60, cost=7.1103251s
Case3 PASS, dataSize=1GB, nMapFiles=60, cost=12.0123006s
Case4 PASS, dataSize=1GB, nMapFiles=60, cost=17.6703582s
Case5 PASS, dataSize=1GB, nMapFiles=60, cost=6.1326302s
Case6 PASS, dataSize=1GB, nMapFiles=60, cost=8.0123164s
Case7 PASS, dataSize=1GB, nMapFiles=60, cost=9.4003026s
Case8 PASS, dataSize=1GB, nMapFiles=60, cost=6.8128708s
Case9 PASS, dataSize=1GB, nMapFiles=60, cost=5.1652438s
Case10 PASS, dataSize=1GB, nMapFiles=60, cost=9.4698508s
--- PASS: TestURLTop (275.26s)
PASS
ok  	talent	275.546s

测试通过,总耗时为:275.546s,比示例Map-Reduce函数速度提升了约3倍

至此lab0的任务二完成

至此lab0完成

完成后的代码已开源在:GitHub - Morgan279/vldbss-2021

总结

与课程预期一致,通过这次lab,我学习到了一些 Golang 的基础知识并对分布式系统有了一个基础的了解。之前我从没有学过go语言,这次lab中Map-Reduce框架的go语言实现提供了一个非常好的go语言编码示例,通过对里面代码的模仿学习,加快了我对go语言的上手速度和对go语言的理解。

这次通过亲手实现了一个简单的Map-Reduce框架,同时利用lab中提供的测试函数来很方便地测试实现的正确性,形成了一个动手到反馈的闭环,让我对分布式系统有了比以往更深入地一个理解,最后感谢主办方对这次lab的精心设计。


http://chatgpt.dhexx.cn/article/0oXRJbgp.shtml

相关文章

Flink OLAP 助力 ByteHTAP 亮相数据库顶会 VLDB

复杂查询 QPS 破百&#xff0c;字节跳动 Flink OLAP 助力 ByteHTAP 亮相数据库顶会 VLDB。 2022 年 9 月 5 日至 9 月 9 日&#xff0c;VLDB 2022 在澳大利亚悉尼举行。字节跳动基础架构研究成果《ByteHTAP: ByteDance’s HTAP System with High Data Freshness and Strong Dat…

湖南大学计算机专业硕士研究导师,湖南大学研究生导师李睿科研论文被世界顶级数据库学术会议VLDB刊发...

李睿老师的论文被国际数据库顶级会议Very Large Data Bases接受并发表。 刊发的论文。 日前&#xff0c;以湖南大学信息科学与工程学院计算机科学系研究生导师李睿为第一作者&#xff0c;湖南大学为第一作者单位的科研论文“Fast Range Query Processing with Strong Privacy P…

PM-LSH: A Fast and Accurate LSH Framework for High-Dimensional Approximate NN Search(VLDB)

由于维数灾难的影响&#xff0c;高维空间中的最近邻(NN)搜索本质上是计算开销巨大的。局部敏感哈希(locality-sensitive hashing, LSH)是一种著名的近似神经网络搜索算法&#xff0c;能够以恒定概率在亚线性时间内回答c-近似神经网络(c-ANN)查询。现有的LSH方法主要基于哈希桶建…

Updatable Learned Index with Precise Positions(VLDB2022)

在现代数据库引擎中&#xff0c;索引在加速查询处理方面起着至关重要的作用。“学习索引”的新范式极大地改变了DBMS中索引结构的设计方式。关键的见解是&#xff0c;索引可以被视为预测数据集中查找键位置的学习模型。虽然这类研究在查找时间和索引大小方面都显示出良好的结果…

VLDB 2023 | 北大河图发布分布式训练神器Galvatron, 一键实现大模型高效自动并行...

关注公众号&#xff0c;发现CV技术之美 本文转自机器之心。 北大河图团队提出了一套面向大模型的自动并行分布式训练系统Galvatron&#xff0c;相比于现有工作在多样性、复杂性、实用性方面均具有显著优势&#xff0c;论文成果已经被 VLDB 2023 接收。 最近一段时间&#xff0c…

Benchmarking Learned Indexes(VLDB2021)

最近学习索引结构的进步建议用近似学习模型来替代现有的索引结构&#xff0c;比如b树。在这项工作中&#xff0c;我们提出了一个统一的基准&#xff0c;它将三种已经学习过的索引结构的优化实现与几种最先进的传统基准进行比较。通过使用四个真实的数据集&#xff0c;我们证明了…

阿里云数据库再获学术顶会认可,一文全览VLDB最新亮点

一年一度的数据库领域顶级会议VLDB 2019于当地时间8月26日-8月30日在洛杉矶圆满落幕。在本届大会上&#xff0c;阿里云数据库产品团队浓墨登场&#xff0c;不仅有多篇论文入选Research Track和Industrial Track&#xff0c;为了进一步加深产学研学术交流&#xff0c;阿里云还在…

2019计算机研究生暑期学校,2019年度VLDB暑期学校

由CCF数据库专业委员会、VLDB中国数据库学院主办&#xff0c;中国人民大学信息学院与数据工程与知识工程教育部重点实验室承办的2019年度VLDB暑期学校(VLDB Summer School 2019)于2019年7月22日在中国人民大学信息楼报告厅隆重举行开班仪式。出席开班仪式的嘉宾有&#xff1a;中…

13 种高维向量检索算法全解析!数据库顶会 VLDB 2021 论文作者干货分享

编者按&#xff1a; 以图搜图、商品推荐、社交推荐等社会场景中潜藏了大量非结构化数据&#xff0c;这些数据被工程师们表达为具有隐式语义的高维向量。为了更好应对高维向量检索这一关键问题&#xff0c;杭州电子科技大学计算机专业硕士王梦召等人探索并实现了「效率和精度最…

Deep Upsupervised Cardinality Estimation 解读(2019 VLDB)

Deep Upsupervised Cardinality Estimation 解读&#xff08;2019 VLDB&#xff09; Deep Upsupervised Cardinality Estimation选择度&#xff08;基数&#xff09;估计问题定义选择度和数据联合分布的关系深度自回归模型如何计算joint distribution编码解码策略具体执行属性的…

VLDB 2021 COCO 论文阅读

Epoch-based Commit and Replication in Distributed OLTP Databases 记录一篇之前读过的论文。。。 整篇论文的核心在于Epoch&#xff0c;将传统数据库以事务为粒度提交和恢复变成了以Epoch为粒度来提交和恢复&#xff0c;这样做的好处就是可以减少2PC和同步复制的时间开销。…

【区块链论文整理】VLDB篇

VLDB (Very Large Data Base&#xff09;是数据库三大顶会之一&#xff0c;近几年也发表了不少水平很高的文章。本文主要针对VLDB 会议中区块链相关的论文进行简单整理。 2021 SlimChain: Scaling Blockchain Transactions through Off-Chain Storage and Parallel Processing…

入选数据库顶会 VLDB:如何有效降低产品级内存数据库快照尾延迟?

阿里云操作系统团队、阿里云数据库团队以及上海交通大学新兴并行计算研究中心一起合作的论文 “Async-fork: Mitigating Query Latency Spikes Incurred by the Fork-based Snapshot Mechanism from the OS Level” 被数据库系统领域顶会 Very Large Data Bases Conferences (V…

VLDB 2023 | 基于擦除的浮点无损压缩(附论文和源码)

大量浮点时间序列数据正以前所未有的高速率生成。一种高效、紧凑、无损的时间序列数据压缩方法对海量数据的应用场景至关重要。现有的大多数浮点无损压缩方法是基于异或操作&#xff0c;但它们没有充分利用尾随零&#xff0c;这通常会导致压缩率不尽如人意。本次为大家带来重庆…

运算符—逻辑运算符

目录 5.逻辑运算符 5.1逻辑运算符概述 5.2短路逻辑运算符 5.逻辑运算符 &#xff08;学完之后要求能够使用逻辑运算符完成逻辑运算&#xff09; 5.1逻辑运算符概述 在数学中&#xff0c;一个数据x&#xff0c;大于3&#xff0c;小于6&#xff0c;我们可以写为这样来表示&am…

C语言关系运算和逻辑运算

一、关系运算 1.关系运算符 每个关系运算符对它左侧值和右侧值进行比较大小的运算 2.关系表达式 用关系运算符连接起来的式子。 若关系为真&#xff0c;关系表达式的值为1&#xff1b; 若关系为假&#xff0c;关系表达式的值为0&#xff1b; 3.优先级 关系运算符优先级低于算术…

C语言复习--逻辑运算符|| 和,!

&& 只有两个条件都为真时&#xff0c;才为真。||只要一个为真&#xff0c;就为真。 逻辑运算符很重要的法则是短路法则。 逻辑运算符的运算顺序都是从左到右计算。 && 当左侧条件为假时&#xff0c;就不计算右侧。 || 都左侧条件为真时&#xff0c;就不计…

C语言:关系运算符逻辑运算符

本节的所讲解的符号&#xff0c;大家在生活中应该都有用过&#xff0c;像我们去商场买东西&#xff0c;都会比较一下价格&#xff0c;是不是相等啊&#xff0c;哪家的贵&#xff0c;哪家的便宜啊。 在C语言中程序中也存在这样的比较&#xff0c;这个时候就需要用到关系运算符了…

C语言逻辑运算符详解

情景模式&#xff1a;现在研发出了一款新的软件&#xff0c;要求使用者必须成年&#xff0c;并且成绩大于等于60&#xff0c;该怎么办呢&#xff1f; 或许你会想到使用嵌套的 if 语句&#xff0c;类似下面这样的代码&#xff1a; #include <stdio.h> int main() {int a…

C 语言 逻辑运算符

文章目录 介绍逻辑运算符一览案例演示 介绍 用于连接多个条件&#xff08;一般来讲就是关系表达式&#xff09;&#xff0c;最终的结果要么是真(非 0 表示)&#xff0c;要么是 假(0 表示) 。 逻辑运算符一览 下表显示了 C 语言支持的所有逻辑运算符。假设变量 A 的值为 1&am…