一、宽列存储场景下的压缩痛点与ScyllaDB适配
宽列存储简单说就是给一个“主数据项”配一大堆附属属性,比如给一个用户配100个消费标签、给一个商品配50个库存记录,这种场景下数据有个特点:附属列要么特别稀疏(很多主项的部分附属列是空的),要么属性值重复度高(比如同一批次商品的品牌字段都一样)。但压缩不是随便开的,开不好反而拖慢系统,比如有些压缩算法太占CPU,数据多的时候直接把服务器跑满;有些算法压缩率低,省不下多少存储空间,白折腾。
ScyllaDB是专门针对大数据场景优化的数据库,它默认带压缩功能,但很多人用的时候要么直接用默认配置踩坑,要么不知道怎么根据宽列的特点调参数。比如我之前帮一个做用户画像的客户调过:他们用ScyllaDB存1亿用户的标签数据,一开始用默认的压缩配置,结果每天备份要花3小时,而且CPU使用率常年在80%以上,后来换了适配宽列的压缩方案,备份时间缩到40分钟,CPU降到40%左右,省了大麻烦。
二、ScyllaDB支持的核心压缩算法对比
ScyllaDB自带的压缩算法有好几种,适合宽列的主要是三种,我用生活化的例子给大家讲清楚:
2.1 LZ4:快读快写的“大众款”
LZ4就像那种折叠快的购物袋,折得快、打开也快,但折完体积不算特别小。它的特点是压缩和解压速度都极快,对CPU的占用非常低,哪怕是数据量特别大的场景,也不会卡。但它的压缩率不算高,适合那种数据重复度一般,但对读写速度要求特别高的场景。
2.2 Snappy:比LZ4稍稳的“实用款”
Snappy有点像那种折叠需要多花1秒,但折完体积小一圈的购物袋。它的压缩率比LZ4高一点,速度也不慢,CPU占用还是很低,是很多场景的默认选项。但它对重复度特别高的数据压缩效果一般,比如如果你的宽列里有很多重复的字符串,它的压缩率会拉胯。
2.3 LZ4HC:慢压快读的“精准款”
LZ4HC是LZ4的“豪华版”,就像那种需要仔细折、花时间,但折完体积小很多的购物袋。它的压缩率比LZ4和Snappy都高,适合重复度高的宽列数据;但它的压缩速度慢,对CPU的占用会高一点,不过解压速度和LZ4差不多,所以适合那种写的时候慢一点没关系,但读的时候要快、要省存储空间的场景。
三、宽列场景下的压缩算法选择方法
选压缩算法不能瞎选,得结合你的具体情况,我给大家总结了三个判断步骤,每个步骤都有实际例子:
3.1 先看宽列数据的重复度
重复度就是看你的附属列里,相同内容出现的概率高不高。比如你存用户的消费标签,里面有“喜欢运动”“喜欢美食”这种重复很多的内容,重复度就高;如果是存用户的实时位置,每个用户的位置都不一样,重复度就低。 判断重复度的方法很简单,你可以取10万条宽列数据,统计一下不同内容的数量占总内容数量的比例:如果比例低于20%,就是高重复度;20%-50%是中等;50%以上是低重复度。
3.2 再看业务的读写要求
业务要求分两种:一种是读写都要快,比如电商的实时库存查询,用户下完单要立刻查到库存,这种不能接受压缩导致的速度变慢;另一种是写的时候慢一点没关系,读的时候要快,比如用户画像的离线分析,每天晚上批量更新标签,第二天早上要快速查标签。
3.3 最后结合服务器的硬件情况
如果你的服务器CPU核数多(比如16核以上),那可以考虑用LZ4HC,哪怕压缩的时候占CPU,也不会影响其他业务;如果CPU核数少(比如8核以下),或者服务器还要跑其他业务,那最好用LZ4或者Snappy,省CPU给其他程序用。
四、ScyllaDB压缩配置的实操示例
接下来我给大家演示完整的配置步骤,技术栈统一用ScyllaDB 5.2版本(目前主流的稳定版),所有操作都是实际生产环境能用的。
4.1 先查看当前的压缩配置
首先登录ScyllaDB的节点,用cqlsh工具连接数据库,然后执行下面的命令查看表的压缩配置:
# 连接ScyllaDB的cqlsh工具,替换<host>为你的数据库节点IP
cqlsh <host> -u <username> -p <password>
# 查看宽列表(假设表名叫user_tags,键空间叫user_profile)的压缩配置
DESCRIBE TABLE user_profile.user_tags;
执行完之后,你会看到类似下面的结果,里面的compression部分就是当前的配置:
{
"class": "org.apache.cassandra.io.compress.LZ4Compressor",
"chunk_length_in_kb": 64,
"enabled": true
}
4.2 根据宽列情况修改压缩配置
举个实际的例子:假设你的user_tags表是宽列,重复度高(比如标签重复度在10%左右),业务是每天晚上批量更新标签(写慢一点没关系),服务器是16核的CPU,那适合用LZ4HC,同时调整块大小(宽列的块大小也很重要,宽列数据多,块太小会导致压缩次数多,影响性能)。 修改配置的命令如下:
# 登录cqlsh后执行,替换键空间和表名
ALTER TABLE user_profile.user_tags
WITH compression = {
'class': 'org.apache.cassandra.io.compress.LZ4Compressor',
'chunk_length_in_kb': 128, # 宽列场景下块大小调大到128KB,减少压缩次数
'enabled': true
};
4.3 验证配置生效并测试性能
修改完之后,你可以用下面的命令验证配置是否生效:
# 再次查看表的压缩配置
DESCRIBE TABLE user_profile.user_tags;
接下来测试性能,ScyllaDB自带了性能测试工具scylla-bench,我们可以用它来测试压缩前后的读写速度和CPU占用:
# 测试写性能,模拟批量写入100万条宽列数据
scylla-bench -mode write -hosts <host> -keyspace user_profile -table user_tags -consistency QUORUM -partitions 1000000 -workload uniform
# 测试读性能,模拟随机读取10万条宽列数据
scylla-bench -mode read -hosts <host> -keyspace user_profile -table user_tags -consistency QUORUM -partitions 100000 -workload uniform
同时你可以用top或者htop命令查看CPU的使用率,用df -h查看存储空间的占用,对比修改前的数值,就能看到优化效果。
五、压缩优化的注意事项
优化压缩的时候有几个坑,我给大家提个醒:
5.1 不要随便改默认配置
很多人一上来就把所有表的压缩都改成LZ4HC,结果发现写性能暴跌,因为LZ4HC的压缩速度比LZ4慢很多,只有高重复度的宽列表才适合用,其他表比如实时交易表,用LZ4就好。
5.2 块大小要适配宽列
块大小是压缩的最小单位,宽列的数据量比普通列大,所以块大小要调大,比如从默认的64KB调到128KB或者256KB,块太小会导致压缩次数多,浪费CPU;块太大的话,解压的时候要读更多数据,影响读性能,一般宽列场景块大小调128KB就差不多。
5.3 备份的时候也要考虑压缩
ScyllaDB的备份默认会压缩数据,如果你已经在表层面开了压缩,备份的时候可以不用再开,避免重复压缩浪费CPU,备份的时候可以配置--compression参数为none。
5.4 升级版本的时候要检查压缩配置
ScyllaDB的新版本可能会优化压缩算法的参数,升级的时候要检查配置,比如有些新版本支持LZ4HC的并行压缩,如果你之前的配置是旧版本的,升级后可以调整参数提升性能。
六、文章总结
宽列存储场景下的ScyllaDB压缩优化,核心就是根据数据的重复度、业务的读写要求和服务器的硬件情况,选对压缩算法和配置。总结下来就是:低重复度的宽列选LZ4,中等重复度选Snappy,高重复度选LZ4HC;同时把块大小调到128KB左右,适配宽列的特点。
优化之后的效果很明显,不仅能节省存储空间,还能降低备份时间和CPU占用,提升系统的整体性能。大家可以按照我给的步骤,先在测试环境试一下,再用到生产环境,避免踩坑。
评论
围绕“ScyllaDB数据压缩的优化方案:宽列存储场景下的压缩算法选择与性能平衡”参与讨论