复述,数据库中怎么对关键进行拆分

介绍

复述,数据库中怎么对关键进行拆分?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

由于复述是单线程运行的,如果一次操作的价值很大会对整个复述的响应时间造成负面影响,所以,业务上能拆则拆、下面举几个典型的分拆方案。

<强>一、单个简单的关键存储的价值很大

我:该对象需要每次都整存整取

可以尝试将对象分拆成几个键值,使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个复述,实例中,降低对单个复述的IO影响;

2:该对象每次只需要存取部分数据

可以像第一种做法一样,分拆成几个键值,也可以将这个存储在一个散列中,每个领域代表一个具体的属性,

使用hget, hmget来获取部分的价值,使用hset, hmset来更新部分属性

<强>二、价值中存储过多的元素

类似于场景一种的第一个做法,可以将这些元素分拆。

以希为例,原先的正常存取流程是hget (hashKey、字段);hset (hashKey、字段值)

现在,固定一个桶的数量,比如10000年每次存取的时候,先在本地计算的哈希值,模除10000年,确定了该领域落在哪个关键上。

newHashKey=hashKey +(集、zset列表也可以类似上述做法

但有些不适合的场景,比如,要保证lpop的数据的确是最早推到列表中去的,这个就需要一些附加的属性,或者是在关键的拼接上做一些工作(比如列表按照时间来分拆)。

<强>三,一个集群存储了上亿的关键

如果关键的个数过多会带来更多的内存空间占用,

我:关键本身的占用(每个关键都会有一个类别前缀)

2:集群模式中,服务端需要建立一些slot2key的映射关系,这其中的指针占用在关键多的情况下也是浪费巨大空间

这两个方面在关键个数上亿的时候消耗内存十分明显(复述,3.2及以下版本均存在这个问题,4.0有优化);

所以减少关键的个数可以减少内存消耗,可以参考的方案是转散列结构存储,即原先是直接使用复述,字符串的结构存储,现在将多个关键存储在一个散列结构中,具体场景参考如下:

1:关键本身就有很强的相关性,比如多个关键代表一个对象,每个关键是对象的一个属性,这种可直接按照特定对象的特征来设置一个新钥匙,哈希结构,原先的关键则作为这个新散列的字段。

举例说明:

原先存储的三个关键

用户。zhangsan-id=123;

用户。zhangsan-age=18;

用户。zhangsan-country=中国;

这三个关键本身就具有很强的相关特性,转成散列存储就像这样关键=用户。zhangsan

字段:id=123;

字段:年龄=18;

:中国=,

即复述中存储的是一个关键:用户。zhangsan,他有三个字段,每个字段+键就对应原先的一个关键。

2:关键本身没有相关性,预估一下总量,采取和上述第二种场景类似的方案,预分一个固定的桶数量

比如现在预估关键的总数为2个亿,按照一个散列存储100个字段来算,需要2亿/100=200 w个桶(200 w个关键占用的空间很少,2个亿可能有将近20 g)

原先比如有三个关键:

user.123456789 user.987654321

用户。678912345

现在按照200W 固定桶分就是先计算出桶的序号 hash(123456789) % 200W , 这里最好保证这个 hash算法的值是个正数,否则需要调整下模除的规则;

这样算出三个key 的桶分别是 1 , 2, 2。 所以存储的时候调用API hset(key, field, value),读取的时候使用 hget (key, field)

Redis数据库中怎么对key进行拆分

注意两个地方:1,hash 取模对负数的处理; 2,预分桶的时候, 一个hash 中存储的值最好不要超过 512 ,100 左右较为合适

四、大Bitmap或布隆过滤器(Bloom )拆分

使用bitmap或布隆过滤器的场景,往往是数据量极大的情况,在这种情况下,Bitmap和布隆过滤器使用空间也比较大,比如用于公司userid匹配的布隆过滤器,就需要512MB的大小,这对redis来说是绝对的大value了。

这种场景下,我们就需要对其进行拆分,拆分为足够小的Bitmap,比如将512MB的大Bitmap拆分为1024个512KB的Bitmap。不过拆分的时候需要注意,要将每个key落在一个Bitmap上。有些业务只是把Bitmap 拆开, 但还是当做一个整体的bitmap看, 所以一个 key 还是落在多个 Bitmap 上,这样就有可能导致一个key请求需要查询多个节点、多个Bitmap。

复述,数据库中怎么对关键进行拆分