I'm wondering if the following function is supported in the MongoDB.
When adding a new shard to the existing sharding cluster which is currently using hashed sharding, some documents in the old shards should be migrated to the new shard.
Question: Does mongodb can handle this process automatically?
Thank you in advance.
Yes. Naively you would imagine an implementation taking a hashcode of a key field, doing a modulo of the number of nodes in a cluster, and putting the value on that node. Adding a node/shard to the cluster would change your modulo'd value, and all data would be scrambled, so adding a node would not be possible.
To work around this issue, distributed systems do it a bit differently. The hash code, instead of mapping to a physical machine, maps to what in mongodb is called a "chunk." In apache spark this would be a partition. There are more chunks than nodes, but many rows of data map to one "chunk."
As an example, you could imagine if you have ten million rows and 5 hosts, you could take the hashcode modulo 100 so that your ten million rows have 100 unique keys with which to deterministically select a node in the cluster, then you manage a mapping that chooses node1 for keys 1-20, node2 for keys 21-40, etc. When you add a fifth node, a rebalancing process can move "chunks" from one node to another, and update the mapping table. Since the mapping table is only recording node locations for a hundred chunks, and not every row, this is manageable.
Mongodb uses a background process to monitor how many chunks are on a node, and move them as needed.
"Chunks" in mongodb: https://docs.mongodb.com/v3.2/core/sharding-data-partitioning/
Reblanacing: https://docs.mongodb.com/v3.2/core/sharding-balancer-administration/