高性能CockroachDB--如何获得更好的性能

 

Gain better performance for CRDB

  • 节点参数设置

    • --attrs,标记node的特点,比如ram大小,硬盘种类,大小等。主要跟replication zone配合使用,zone能通过这些特点来进行库、表、行级别的数据分离存储。比如限制某个表的数据只能存储在attrs硬盘为ssd的store上。

    • --cache,分给rocksdb的内存大小,越多读性能越好,建议25%的内存容量。

    • --locality,标明node的地域位置,主要配合replication zone使用限制数据存储地域,也是特性follow workload必要参数,只有设置了它,lease才能自动移往负载来源node以减少时延(当node靠得很近时不设置)。

    • --max-sql-memory,用于sql session和其他sql运行时分配的缓存,更大的缓存可以允许更多的并发连接,建议25%的内存。

    • --store,一个store就是一个rocksdb实例,使用多个store,并给每个store分配一个独立的硬盘,在cpu等其他因素充裕的情况下可以提高并发。

  • Replication Zone,通过zone,可以配置集群中replica的副本数量,限定数据存储地点,配置垃圾回收(较旧的MVCC数据)时间等,配置粒度从cluster,database,table,到row。配置方法通过参数写入YAML文件配置,共有这些配置参数:

    • range_min_bytes,range的最小大小。

    • range_max_bytes,range最大大小,默认64M。

    • ttlseconds,垃圾回收时间,回收旧的MVCC数据,默认是25小时,超过25小时的数据会被异步清理。

    • num_replicas,副本数量,默认为3。

    • constraints,一串JSON数据,限制replica位置的参数,前面设置的node参数如locality和attrs,都是这里的限制条件,比如:

      constraints: {"+region=us-west1": 2, "+region=us-central1": 1}

      限制第二份replica只能存在us-west1,第一份replica只能存在us-central1。

    YAML文件的粒度范围从cluster到row,并且range的每一个replica都可以具体配置,因而很灵活,可以根据自己的需求来进行具体的定制规则,比如实现在一个集群中存储多个应用的数据,但是将他们存储在不同位置,相互不影响。

  • 集群设置,这些设置是集群范围内的设置,并且都是比较内核级别的设置,可能会造成很大影响,因而需要谨慎:

    • kv.allocator.lease_rebalancing_aggressiveness,是否更激进的根据负载平衡lease分布,默认为1,0~1之间更保守,>1更激进。一般来讲,当出现某些node负载一直高于其他node时应该设置更高的系数。

    • kv.allocator.load_based_lease_rebalancing.enabled,是否根据负载和时延来平衡lease,一般来讲建议开启。

    • kv.allocator.range_rebalance_threshold,当该node的负载等因素大于集群平均值多少时判断需要平衡,默认为5%,如果因为平衡影响了性能可以将其设置的高一些。

    • kv.range.backpressure_range_size_multiplier,range在因为write阻塞前能够增长的最大range_max_bytes倍数大小而不用splitting,默认是2倍,即如果没有碰到write block那么小于128M的range依然不用被splitting,可以减少因为splitting产生的压力。

    • rocksdb.min_wal_sync_interval,每多少秒刷新RocksDB log到硬盘,默认为0,这个不应该修改。

    • server.consistency_check.interval,多久检测一次range的每个replica一致性,默认是24h,这个弄在每天负载最低的时候检测最好。

    • server.time_until_store_dead,上一次store活跃的时间间隔(发出新的gossip信息),超过则其他store认为该store已经挂了,默认为5min。

    • sql.defaults.distsql,是否开启分布式SQL,有不开启,根据情况选择是否使用,和开启三种,默认是第二种。

    • sql.distsql.distribute_index_joins,是否开启分布式hash join,减一开启。

    • sql.distsql.merge_joins.enabled,是否使用merge join,当join的参数有序时会使用merge join,建议开启。

    这些集群参数都可以在cluster运行时设置。

  • SQL优化

    • 使用TRUNCATE而不是DELETE去删除全表数据,前者会直接删除全表然后重建新表,后者会产生很多事务去删除每行数据。

    • 如果可以,尽可能的将多行数据放到一个UPDATA,INSERT或者DELETE中。crdb性能最好为100~2000的batch size。

    • 批量导入数据IMPORT比INSERT快很多。

    • crdb能够并行执行一个事务里的语句,在每个语句后使用RETURNING NOTHINGcrdb在接受每个语句后立即返回,然后并行的执行各个语句,crdb会自动检测语句间是否有冲突然后转为串行执行,因而可以随意使用该特性。

    • 使用column family,对于表中几乎不使用的数据,应该设置另外的column family将其与热点列分开存储。

    • 使用interleave table,可以将经常一起在query中被使用的不同表的数据存在同一range里,原理是将其中一个表的key加上另一个表的key前缀。

    • 对于primary key和unique index,尽量使用UUID和gen_random_uuid(),这回产生随机的唯一值,可以将数据分布到不同range,避免热点数据聚集。

    • 对于长时间持续的query(如OLAP应用),建议使用... AS OF SYSTEM TIME来将query时间往前移一点,从而减少与当前事务的冲突。

    • 对于次级索引,如果使用次级索引的query经常涉及某些列数据,可以使用STORING将这些列跟次级索引存储在同一KV对中,以避免还要到主键索引中二次查找。

你可能感兴趣的:(cockroachdb)