多云适配,ClickHouse分层对象存储已全面适配各云厂商

2021-12-31 19:44:47 浏览数 (1)

这应该是 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;
            }
        }

如果你的使用场景有分层对象存储的需求,就赶紧去试一试吧。

0 人点赞