关于后端:MongoDB-分片规则

1次阅读

共计 2464 个字符,预计需要花费 7 分钟才能阅读完成。

每日一句

生命自身毫无意义,只有死亡能力让你邃晓兽性的真谛!

每日一句

Ideal is the beacon. Without ideal, there is no secure direction; without direction, there is no life.
现实是指路明灯。没有现实,就没有动摇的方向; 没有方向,就没有生存。

概述

对汇合进行分片时, 你须要抉择一个 片键(Shard Key), shard key 是每条记录都必须蕴含的, 且建设了索引的单个字段或复合字段,MongoDB 依照片键将数据划分到不同的 数据块 中, 并将 数据块 平衡地散布到所有分片中.

为了依照片键划分数据块,MongoDB 应用如下形式调配:

  • 基于哈希的分片形式(随机平均分配)
  • 基于范畴的分片形式(数值大小调配)

用什么字段当片键都能够,如:nickname 作为片键,但肯定是必填字段。

哈希策略

对于 基于哈希的分片 ,MongoDB 计算一个字段的哈希值, 并用这个哈希值来创立数据块.

在应用基于哈希分片的零碎中, 领有”相近”片键的文档 很可能不会 存储在同一个数据块中, 因而数据的分离性更好一些.

应用 nickname 作为片键,依据其值的哈希值进行数据分片

sh.shardCollection("articledb.comment",{"nickname":"hashed"})

范畴策略

对于 基于范畴的分片 ,MongoDB 依照片键的范畴把数据分成不同局部.

假如有一个数字的片键: 设想一个从负无穷到正无穷的直线, 每一个片键的值都在直线上画了一个点.MongoDB 把这条直线划分为更短的不重叠的片段, 并称之为 数据块 , 每个数据块蕴含了片键在肯定范畴内的数据.

在应用片键做范畴划分的零碎中, 领有”相近”片键的文档很可能存储在同一个数据块中, 因而也会存储在同一个分片中.

如应用作者年龄字段作为片键,依照点赞数的值进行分片:

sh.shardCollection("articledb.author",{"age":1})

留神

1)一个汇合只能指定一个片键,否则报错。

2)一旦对一个汇合分片,分片键和分片值就不可扭转。如:不能给汇合抉择不同的分片键、不能更新分片键的值。

3)依据 age 索引进行调配数据。

两种策略比照

基于范畴的分片形式提供了更高效的范畴查问, 给定一个片键的范畴, 散发路由能够很简略地确定哪个数据块存储了申请须要的数据, 并将申请转发到相应的分片中. 不过, 基于范畴的分片会导致数据在不同分片上的不平衡, 有时候, 带来的消极作用会大于查问性能的踊跃作用. 比方, 如果片键所在的字段是线性增长的, 肯定工夫内的所有申请都会落到某个固定的数据块中, 最终导致散布在同一个分片中. 在这种状况下, 一小部分分片承载了集群大部分的数据, 零碎并不能很好地进行扩大.

基于哈希的分片形式以范畴查问性能的损失为代价, 保障了集群中数据的平衡. 哈希值的随机性,使数据随机散布在每个数据块中, 因而也随机散布在不同分片中. 然而也正因为随机性, 一个范畴查问很难确定应该申请哪些分片, 通常为了返回须要的后果, 须要申请所有分片.

如无非凡状况,个别举荐应用 Hash Sharding。而应用 _id 作为片键是一个不错的抉择,因为它是必有的,你能够应用数据文档 _id 的哈希作为片键。

这个计划可能是的读和写都可能均匀散布,并且它可能保障每个文档都有不同的片键所以数据块可能很精密。仿佛还是不够完满,因为这样的话对多个文档的查问必将命中所有的分片。虽说如此,这也是一种比拟好的计划了。

美文佳句

一个人的自愈能力越强,才越有可能靠近幸福。做一个寡言,却心有一片海的人,不伤人害己,于恬淡中,温和自在。

面试题

Math.round(11.5) 等于多少?Math.round(-11.5) 等于多少?

答:Math.round(11.5) 的返回值是 12,Math.round(-11.5) 的返回值是 -11。
四舍五入的原理是在参数上加 0.5 而后向下取整。

LeetCode 11 盛最多水的容器

题目链接

https://leetcode-cn.com/problems/container-with-most-water/

题目形容

给定一个长度为 n 的整数数组 height。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。

找出其中的两条线,使得它们与 x 轴独特形成的容器能够包容最多的水。

返回容器能够贮存的最大水量。

阐明:你不能歪斜容器。

示例

示例 1:

 输出:[1,8,6,2,5,4,8,3,7]
输入:49 
解释:图中垂直线代表输出数组 [1,8,6,2,5,4,8,3,7]。在此状况下,容器可能包容水(示意为蓝色局部)的最大值为 49。

示例 2:

 输出:height = [1,1]
输入:1

提醒

n == height.length
2 <= n <= 105
0 <= height[i] <= 104

题解

题解一:双指针法

public class Solution {public int maxArea(int[] height) {
        int l = 0, r = height.length - 1;
        int ans = 0;
        while (l < r) {int area = Math.min(height[l], height[r]) * (r - l);
            ans = Math.max(ans, area);
            if (height[l] <= height[r]) {++l;}
            else {--r;}
        }
        return ans;
    }
}

复杂度剖析

  • 工夫复杂度:O(N),双指针总计最多遍历整个数组一次。
  • 空间复杂度:O(1),只须要额定的常数级别的空间。

如果没有重写 initialValue 办法就间接 get 会怎么?

如果在没有 set 的时候就调用 get,会调用 initialValue 办法初始化内容,默认 value 为空。

通常状况下咱们能够重写 initialvalue 来赋值。

ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

你好,我是 yltrcc,日常分享技术点滴,欢送关注我:ylcoder

正文完
 0