OSS Select使用场景及技巧

本文涉及的产品
对象存储 OSS,20GB 3个月
日志服务 SLS,月写入数据量 50GB 1个月
文件存储 NAS,50GB 3个月
简介: 背景介绍 OSS Select是OSS近期推出的一项新功能,它可以对OSS上的类CSV文件(其他类型文件比如Json也会很快推出)在服务器端运行SQL查询,仅将查询结果返回给客户端。举例来说,假如你有一个10GB的csv日志文件,有一列数据是错误码,想把其中所有错误码等于500的日志找出来,用OSS Select仅仅返回错误码是500的日志,在从而降低用户的数据传输成本以及处理数据的成本,相比在客户端下载整个文件再处理在性能上也可以提高最多到6倍以上。

背景介绍

OSS SelectOSS近期推出的一项新功能,它可以对OSS上的类CSV文件(其他类型文件比如Json也会很快推出)在服务器端运行SQL查询,仅将查询结果返回给客户端。举例来说,假如你有一个10GBcsv日志文件,有一列数据是错误码,想把其中所有错误码等于500的日志找出来,用OSS Select仅仅返回错误码是500的日志,在从而降低用户的数据传输成本以及处理数据的成本,相比在客户端下载整个文件再处理在性能上也可以提高最多到6倍以上。

那这个功能可以用在哪些场景呢,打开它的正确姿势是什么呢?下面就来一一讲解。

 

应用场景

日志文件分析

阿里云上的应用程序每天都在产生大量的日志文件,OSS是保存这些日志最可靠最经济的方式之一。通常的做法是每隔一段时间(比如一个小时)产生一个日志文件,在大部分情况下这些日志文件是GZIP压缩的。如果需要对这些日志文件做非常复杂的交叉查询,那阿里云的日志服务显然是不二的选择,但如果只是偶尔需要对这些文件做一些查询,比如在本文开头中描述的情况下,那OSS Select是更加简单、经济的做法。

OSS  Select支持类CSV文件,用户可以在Select请求中指定特定的行、列分隔符以及转义字符。简单插一句,CSV文件中如果一列数据包含换行符,那就需要将这些数据用转义字符将该列数据包含起来,从而将这个换行符转义。


比如用户有一个如下格式的nginx access log文件:

$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"

如果我们要找出所有客户端IP192.168.0.1或者user agent包含chrome字符的请求的status,那可以用下面的Python代码来实现:

sql = “select _6 from ossobject where _1 = ‘192.168.0.1’ or _9 like ‘%chrome%’"

input_format = {‘RecordDelimiter’:’\n’, ‘FieldDelimiter’:’\t’, ‘QuoteCharacter’:’”’, ‘CompressionType’:”GZIP”}

 

result = self.bucket.select_object(key, sql, select_params = input_format)

content = result.read()

 

如果想仅仅统计status 不等于200的请求数呢?那就可以用下面这个SQL实现

sql = “select count(*) from ossobject where _6 = ‘200’"

小伙伴们肯定注意到这里用了’200’而不是200,其实这里两者都是可以的,但是用’200’速度会更快一些,因为CSV文件的内容都是字符串。

如果我的日志文件第一行是CSV列名怎么办?可以用CsvHeaderInfo这个参数,并且可以在SQL中愉快的用列名了。

input_format = {‘RecordDelimiter’:’\n’, ‘FieldDelimiter’:’\t’, ‘QuoteCharacter’:’”’, ‘CompressionType’:”GZIP”, ‘CsvHeaderInfo’:’Use’}

sql = “select count(*) from ossobject where status=’200’”

如果我的日志文件有注释行怎么办呢?简单,用CommentCharacter这个参数指定注释行的开头字母,这样所有的注释行就会被跳过。

input_format = {‘RecordDelimiter’:’\n’, ‘FieldDelimiter’:’\t’, ‘QuoteCharacter’:’”’, ‘CompressionType’:”GZIP”, ‘CsvHeaderInfo’:’Use’, ‘CommentCharacter’:’#’}

更加复杂的情况来了,如果我的日志文件有的行缺数据,默认的行为是缺的数据列会被当做null来处理。但我想完全忽略这些缺数据的行怎么办?容易,用SkipPartialDataRecord这个参数为true就好了:

input_format = {‘RecordDelimiter’:’\n’, ‘FieldDelimiter’:’\t’, ‘QuoteCharacter’:’”’, ‘CompressionType’:”GZIP”, ‘CsvHeaderInfo’:’Use’, ‘CommentCharacter’:’#’, ‘SkipPartialdataRecord’:’true’}

还有,我希望返回的结果用不同的行列分隔符,比如用逗号表示列分隔符,用’\r\n‘表示行分隔符?

input_output_format = {‘RecordDelimiter’:’\n’, ‘FieldDelimiter’:’\t’, ‘QuoteCharacter’:’”’, ‘CompressionType’:”GZIP”, ‘CsvHeaderInfo’:’Use’, ‘CommentCharacter’:’#’, ‘SkipPartialdataRecord’:’true’, ‘OutputRecordDelimiter':’\r\n’, ‘OutputFieldDelimeter’:’,’}

如果我的日志文件有100G,且不是压缩的,上面的方法处理速度有点慢怎么破?分片查询可以解决这个问题。首先,上传文件后马上可以用下面的代码给这个日志文件创建分片信息,并返回总的分片数:

result = self.bucket.create_select_object_meta(key, {‘RecordDelimiter’:’\n’, ‘FieldDelimiter’:’\t’, ‘QuoteCharacter’:’”’}

total_splits = result.splits

然后用Python多线程运行下面的代码,每个线程指定不同的分片范围—----start_rangeend_range表示起始分片号,从0total_splits - 1

def select_by_range(start_range, end_range):

       input_output_format = {‘RecordDelimiter’:’\n’, ‘FieldDelimiter’:’\t’, ‘QuoteCharacter’:’”’, ‘CompressionType’:”GZIP”, ‘CsvHeaderInfo’:’Use’, ‘CommentCharacter’:’#’, ‘SkipPartialdataRecord’:’true’, ‘OutputRecordDelimiter':’\r\n’, ‘OutputFieldDelimeter’:’,’, ‘SplitRange’:[start_range, end_range]}

 

       result = self.bucket.select_object(key, sql, select_params = input_output_format)

       return result

 

值得注意的是如果该文件的分片信息不存在,创建分片信息本身需要扫描整个文件。一旦创建完成就会被保存下来,下一次调用创建分片信息的函数时会直接返回结果。因此建议的策略是如果该文件需要分片查询,那么文件上传后就马上创建分片信息,从而避免在使用的时候需要扫描整个文件的开销。


最后,如果需要分析一个OSS前缀下的所有文件,有什么好办法吗?目前OSS Select API针对的是单个文件,如果要扫描整个目录,那需要首先调用bucketList API返回该前缀下的所有文件,然后对这个列表分别调用Select API,可以单线程也可以多线程调用。


普通文本文件

如果我的文件只是普通文本文件而不是CSVOSS Select对我而言有什么用呢?其实即使是普通文本文件(比如无固定格式的日志),你仍然可以用OSS Select实现服务器端grep的效果。比如,我可以用’\n’同时作为行列分隔符,这意味着可以用_1表示一整行信息。如果要搜索文本中所有含对象存储的行,只需要用select * from ossobject where _1 like ‘%对象存储%’。对于大文件而言,这比直接下载然后用grep要更简单高效。


和大数据平台结合

当大数据平台处理的数据源是OSS对象时,OSS Select还可以和大数据平台配合使用。目前阿里云的数据湖分析(Data Lake Analytics)服务支持OSS Select。只需要在Query语句前加一个Hint /*+oss-select-enabled=true*/即可。值得注意的是,如果用户输入的SQL语句可以有效过滤OSS数据的话,使用OSS Select后返回给Data Lake Analytics服务的数据可以有效减少,从而可以减少用户查询的时间并降低用户的总体成本。

另外,OSS Select还可以和Spark配合使用,我们将会有专门的文章详细讲解。


敏感数据脱敏

假如你有一些文件里包含一些敏感信息,比如身份证号码,但同时你需要给你的用户共享该文件中的其他信息。这个怎么做到呢?最简单的做法是你可以在你的服务里包一层OSS Select API,该API里调用Select接口只把不敏感的数据返回给你的用户。尤其是如果你的服务需要在欧洲上线的话,欧盟的GDPR对数据共享有着严格的限制。OSS Select可以简化包含敏感信息的数据的脱敏。


使用技巧

下面分享一些OSS Select使用过程中的小技巧,这些小技巧可以一方面提高用户查询的性能,另一方面在某些情况下降低使用成本。

  1. 显式地选择所需要的列,而不是select *。这可以有效减少数据返回量,提高查询响应时间.
  2. Where语句中优先使用字符串比较。当某些情况下既可以用字符串比较,也可以用Cast函数转换成其他类型后再比较。用字符串比较可以省去类型转换,从而使得查询更加高效。
  3. Where语句中,把运行速度更快的表达式放在左边。由于Where条件是从左到右执行,左边的运算结果可以短路(short cut)掉右边的表达式。因此将表达式按照执行代价从左到右排列是一个最优的做法。关于不同表达式执行的代价,下面是从小到大的通常排序:字符串简单比较(=或者><),整数的比较和四则运算,浮点数的比较和四则运算,日期的比较,Decima的比较和四则运算,字符串的LIKE,字符串连接(concat)
  4. 合理使用IN语句。当需要对同一列进行多个数值的比较时,如果需要比较的数值在3个以内,那用or可能是一个更加简便的方法,但如果多余三个,那用IN更加简单高效。请注意OSS Select目前支持在IN中包含最多1024项。
  5. 合理使用分片查询。当文件较小时,直接查询更加经济高效,因为创建分片信息本身需要扫描整个文件一遍,而且这个过程也是收费的。当文件很大且需要反复查询时,使用分片查询可以极大的提高速度(可以提高数十倍,取决于客户端并发数)。
  6. 如何使用OutputRawData参数。OSS Select默认是用一个专门的格式包装返回的数据,该格式可以汇报进度查询执行进度,并且保活连接。但是如果被查询文件本身不是很大,或者使用的SQL语句过滤条件不强时,直接使用OutputRawData可以省去Frame本身的流量并提高客户端获取数据的速度。


总结

OSS Select功能旨在降低访问OSS时的数据传输量,简化客户端处理数据,并提高访问OSS的端到端性能以及降低客户的总体成本。他不仅可以用来直接查询类CSV文件(压缩或者未压缩)或者实现Server端的grep文本文件,同时和大数据平台如Data Lake Analyitcs或者Spark配合时,可以使整个查询过程更加高效并降低成本。

 

关于OSS Select有任何问题,欢迎留言一起讨论。

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
存储 编解码 弹性计算
云存储-对象存储的介绍和使用场景 | 学习笔记
快速学习云存储-对象存储的介绍和使用场景
云存储-对象存储的介绍和使用场景 | 学习笔记
|
存储 对象存储
OSS产品Bucket分级的使用场景及注意事项
oss产品允许用户设置三种类型的Bucket,分别是标准(Standard)、低频(IA)、归档(Archive)三级存储类型,Bucket的类型决定了用户Object上传后的默认类型。
4492 0
|
存储 分布式计算 大数据
OSS Select应用实践与使用技巧系列
OSS Select,让用户可以直接使用SQL语句,从OSS文件中选取所需要的内容,而不必读取整个文件的内容。企业级用户使用OSS Select,可将查询条件下推到OSS,为计算应用加速,更好地发挥数据的价值。
7061 0
|
SQL 分布式计算 大数据
Spark读写OSS并使用OSS Select来加速查询
Spark读写OSS 基于这篇文章搭建的CDH6以及配置,我们来使Spark能够读写OSS(其他版本的Spark都是类似的做法,不再赘述)。 由于默认Spark并没有将OSS的支持包放到它的CLASSPATH里面,所以我们需要执行如下命令下面的步骤需要在所有的CDH节点执行 进入到$CDH_HO.
4548 0
|
SQL 存储 对象存储
在控制台使用OSS Select
对象存储OSS(Object Storage Service)具有海量、可靠、安全、高性能、低成本的特点。OSS提供标准、低频、归档类型,覆盖多种数据从热到冷的存储需求,单个文件的大小从1字节到48.8TB,可以存储的文件个数无限制。
2546 0
|
SQL API 对象存储
OSS重磅推出OSS Select——使用SQL选取文件的内容
OSS重磅推出OSS Select功能,可以直接使用简单的SQL语句,从OSS的文件中选取所需要的内容
27907 0
|
4月前
|
机器学习/深度学习 人工智能 专有云
人工智能平台PAI使用问题之怎么将DLC的数据写入到另一个阿里云主账号的OSS中
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
14天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
3月前
|
存储 机器学习/深度学习 弹性计算
阿里云EMR数据湖文件系统问题之OSS-HDFS全托管服务的问题如何解决
阿里云EMR数据湖文件系统问题之OSS-HDFS全托管服务的问题如何解决
|
4月前
|
消息中间件 分布式计算 DataWorks
DataWorks产品使用合集之如何使用Python和阿里云SDK读取OSS中的文件
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。

相关产品

  • 对象存储