这应该是 2021 年我的最后一篇原创啦,提前祝大家新年快乐。
在早前这篇文章中 《ClickHouse已支撑S3和HDFS存储的零拷贝复制》,我介绍过 ClickHouse 为了更好的适应当前云原生的发展,利用多层存储的机制,打通了 S3 这样的对象存储。
云服务发展到现在,能多云适配、上云下云,也是非常重要的一个命题。
在对象存储这一块,AWS 的 S3、华为云的 OBS、腾讯云的 COS 以及 阿里云的 OSS,ClickHouse 现在已经全面适配。
从 ClickHouse 的源码来看,其实现机制非常简单。因为 S3 作为对象存储的鼻祖,其他厂商都对其看齐,纷纷兼容 S3 的协议。所以 ClickHouse 只需要实现 S3 的对接,即可多云适配了。
ClickHouse源码节选
代码语言:javascript复制 URI::URI(const Poco::URI & uri_)
{
/// Case when bucket name represented in domain name of S3 URL.
/// E.g. (https://bucket-name.s3.Region.amazonaws.com/key)
/// https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#virtual-hosted-style-access
static const RE2 virtual_hosted_style_pattern(R"((. ).(s3|cos|obs|oss)([.-][a-z0-9-.:] ))");
...
...
static constexpr auto S3 = "S3";
static constexpr auto COSN = "COSN";
static constexpr auto COS = "COS";
static constexpr auto OBS = "OBS";
static constexpr auto OSS = "OSS";
...
...
uri = uri_;
storage_name = S3;
if (uri.getHost().empty())
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Host is empty in S3 URI.");
String name;
String endpoint_authority_from_uri;
if (re2::RE2::FullMatch(uri.getAuthority(), virtual_hosted_style_pattern, &bucket, &name, &endpoint_authority_from_uri))
{
is_virtual_hosted_style = true;
endpoint = uri.getScheme() "://" name endpoint_authority_from_uri;
validateBucket(bucket, uri);
if (!uri.getPath().empty())
{
/// Remove leading '/' from path to extract key.
key = uri.getPath().substr(1);
}
boost::to_upper(name);
if (name != S3 && name != COS && name != OBS && name != OSS)
{
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Object storage system name is unrecognized in virtual hosted style S3 URI: {}", quoteString(name));
}
if (name == S3)
{
storage_name = name;
}
else if (name == OBS)
{
storage_name = OBS;
}
else if (name == OSS)
{
storage_name = OSS;
}
else
{
storage_name = COSN;
}
}
如果你的使用场景有分层对象存储的需求,就赶紧去试一试吧。