Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i0249-0001sp-V8 for pgsql-hackers@arkaria.postgresql.org; Tue, 20 Aug 2019 11:12:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1i0247-0004IX-9F for pgsql-hackers@arkaria.postgresql.org; Tue, 20 Aug 2019 11:12:39 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i0247-0004IP-0k for pgsql-hackers@lists.postgresql.org; Tue, 20 Aug 2019 11:12:39 +0000 Received: from mail-lf1-f52.google.com ([209.85.167.52]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1i0243-0002hi-Ny for pgsql-hackers@postgresql.org; Tue, 20 Aug 2019 11:12:38 +0000 Received: by mail-lf1-f52.google.com with SMTP id h28so3800905lfj.5 for ; Tue, 20 Aug 2019 04:12:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=1jF7yXOYc0jSS4g2SSsz+9+Ok0WJpTHyarQ440LHrIQ=; b=bD+i6PVKdYmEgYCy9eyasWJxF9Q/1dz29J9pg7OkDtD0Sivt5ir97tTcMgukgmZwD9 4BBysHxCha/tF8OHh11p5wnqnXsr91HxFOkQoq/Gn2Wf/U6ZxWeIr64Y+caPmK2xtMfV ++eY/Y2csjmJo97N/x0NsgPp5D939FMw9cyPQ9bQejmTwT15h3qeNSlu5bju3PqCD0iU Sn/xxEvQRe9S0lzxznW1/U5xWYe8gjTpv6RjYBd7ykEvBdWhyACAigokWMgZHFtwQQLN sjf1kBGUX44htPpW92lrtIIzZuKcAs2Mp5tLwCA/Uu3gqYlCuy+S20AP+5SlCsncMn1Y jKEA== X-Gm-Message-State: APjAAAVktg4DQqy0mA5Di5/44TtuSe5IObRvE+ZHPHTO67ueZCi7uD78 VnNpXpdJCCAza6fLBOTCvJq9ZKI6 X-Google-Smtp-Source: APXvYqxkSNICCtb5cvh1ny5LgM5rZv5ATVKlJrUUAyDeeHn0zeytJIr+0gwb+cP2ZfSYDFyhroi3fA== X-Received: by 2002:ac2:4901:: with SMTP id n1mr15015459lfi.0.1566299554406; Tue, 20 Aug 2019 04:12:34 -0700 (PDT) Received: from [192.168.1.10] (dsl-hkibng22-54f8d6-97.dhcp.inet.fi. [84.248.214.97]) by smtp.gmail.com with ESMTPSA id g12sm2815429lfc.96.2019.08.20.04.12.33 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 20 Aug 2019 04:12:33 -0700 (PDT) Subject: Re: Zedstore - compressed in-core columnar storage To: Justin Pryzby , Alexandra Wang Cc: Ashwin Agrawal , Ashutosh Sharma , PostgreSQL mailing lists References: <5ceff1bd.1c69fb81.704ee.a5b1SMTPIN_ADDED_BROKEN@mx.google.com> <20190818193533.GL11185@telsasoft.com> <20190820020425.GX11185@telsasoft.com> From: Heikki Linnakangas Message-ID: Date: Tue, 20 Aug 2019 14:12:32 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: <20190820020425.GX11185@telsasoft.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 20/08/2019 05:04, Justin Pryzby wrote: >>> it looks like zedstore >>> with lz4 gets ~4.6x for our largest customer's largest table. zfs using >>> compress=gzip-1 gives 6x compression across all their partitioned >>> tables, >>> and I'm surprised it beats zedstore . I did a quick test, with 10 million random IP addresses, in text format. I loaded it into a zedstore table ("create table ips (ip text) using zedstore"), and poked around a little bit to see how the space is used. postgres=# select lokey, nitems, ncompressed, totalsz, uncompressedsz, freespace from pg_zs_btree_pages('ips') where attno=1 and level=0 limit 10; lokey | nitems | ncompressed | totalsz | uncompressedsz | freespace -------+--------+-------------+---------+----------------+----------- 1 | 4 | 4 | 6785 | 7885 | 1320 537 | 5 | 5 | 7608 | 8818 | 492 1136 | 4 | 4 | 6762 | 7888 | 1344 1673 | 5 | 5 | 7548 | 8776 | 540 2269 | 4 | 4 | 6841 | 7895 | 1256 2807 | 5 | 5 | 7555 | 8784 | 540 3405 | 5 | 5 | 7567 | 8772 | 524 4001 | 4 | 4 | 6791 | 7899 | 1320 4538 | 5 | 5 | 7596 | 8776 | 500 5136 | 4 | 4 | 6750 | 7875 | 1360 (10 rows) There's on average about 10% of free space on the pages. We're losing quite a bit to to ZFS compression right there. I'm sure there's some free space on the heap pages as well, but ZFS compression will squeeze it out. The compression ratio is indeed not very good. I think one reason is that zedstore does LZ4 in relatively small chunks, while ZFS surely compresses large blocks in one go. Looking at the above, there is on average 125 datums packed into each "item" (avg(hikey-lokey) / nitems). I did a quick test with the "lz4" command-line utility, compressing flat files containing random IP addresses. $ lz4 /tmp/125-ips.txt Compressed filename will be : /tmp/125-ips.txt.lz4 Compressed 1808 bytes into 1519 bytes ==> 84.02% $ lz4 /tmp/550-ips.txt Compressed filename will be : /tmp/550-ips.txt.lz4 Compressed 7863 bytes into 6020 bytes ==> 76.56% $ lz4 /tmp/750-ips.txt Compressed filename will be : /tmp/750-ips.txt.lz4 Compressed 10646 bytes into 8035 bytes ==> 75.47% The first case is roughly what we do in zedstore currently: we compress about 125 datums as one chunk. The second case is roughty what we would get, if we collected on 8k worth of datums and compressed them all as one chunk. And the third case simulates the case we would allow the input to be larger than 8k, so that the compressed chunk just fits on an 8k page. Not too much difference between the second and third case, but its pretty clear that we're being hurt by splitting the input into such small chunks. The downside of using a larger compression chunk size is that random access becomes more expensive. Need to give the on-disk format some more thought. Although I actually don't feel too bad about the current compression ratio, perfect can be the enemy of good. - Heikki