The sharding of the block cache is limited to 2*20 pieces.

Summary:
The numbers of shards that the block cache is divided into is
configurable. However, if the user specifies that he/she wants
the block cache to be divided into more than 2**20 pieces, then
the system will rey to allocate a huge array of that size) that
could fail.

It is better to limit the sharding of the block cache to an
upper bound. The default sharding is 16 shards (i.e. 2**4)
and the maximum is now 2 million shards (i.e. 2**20).

Also, fixed a bug with the LRUCache where the numShardBits
should be a private member of the LRUCache object rather than
a static variable.

Test Plan:
run db_bench with --cache_numshardbits=64.

Task ID: #

Blame Rev:

Reviewers: heyongqiang

Reviewed By: heyongqiang

Differential Revision: https://reviews.facebook.net/D5013
main
Dhruba Borthakur 12 years ago
parent a4f9b8b49e
commit e5fe80e4e3
  1. 7
      db/db_bench.cc
  2. 20
      util/cache.cc

@ -1048,7 +1048,12 @@ int main(int argc, char** argv) {
} else if (sscanf(argv[i], "--cache_size=%ld%c", &n, &junk) == 1) { } else if (sscanf(argv[i], "--cache_size=%ld%c", &n, &junk) == 1) {
FLAGS_cache_size = n; FLAGS_cache_size = n;
} else if (sscanf(argv[i], "--cache_numshardbits=%d%c", &n, &junk) == 1) { } else if (sscanf(argv[i], "--cache_numshardbits=%d%c", &n, &junk) == 1) {
FLAGS_cache_numshardbits = n; if (n < 20) {
FLAGS_cache_numshardbits = n;
} else {
fprintf(stderr, "The cache cannot be sharded into 2**%d pieces\n", n);
exit(1);
}
} else if (sscanf(argv[i], "--bloom_bits=%d%c", &n, &junk) == 1) { } else if (sscanf(argv[i], "--bloom_bits=%d%c", &n, &junk) == 1) {
FLAGS_bloom_bits = n; FLAGS_bloom_bits = n;
} else if (sscanf(argv[i], "--open_files=%d%c", &n, &junk) == 1) { } else if (sscanf(argv[i], "--open_files=%d%c", &n, &junk) == 1) {

@ -275,21 +275,22 @@ class ShardedLRUCache : public Cache {
LRUCache* shard_; LRUCache* shard_;
port::Mutex id_mutex_; port::Mutex id_mutex_;
uint64_t last_id_; uint64_t last_id_;
int numShardBits;
static inline uint32_t HashSlice(const Slice& s) { static inline uint32_t HashSlice(const Slice& s) {
return Hash(s.data(), s.size(), 0); return Hash(s.data(), s.size(), 0);
} }
static uint32_t Shard(uint32_t hash) { uint32_t Shard(uint32_t hash) {
return hash >> (32 - kNumShardBits); return hash >> (32 - numShardBits);
} }
void init(size_t capacity, int numShardBits) { void init(size_t capacity, int numbits) {
kNumShardBits = numShardBits; numShardBits = numbits;
kNumShards = 1 << kNumShardBits; int numShards = 1 << numShardBits;
shard_ = new LRUCache[kNumShards]; shard_ = new LRUCache[numShards];
const size_t per_shard = (capacity + (kNumShards - 1)) / kNumShards; const size_t per_shard = (capacity + (numShards - 1)) / numShards;
for (int s = 0; s < kNumShards; s++) { for (int s = 0; s < numShards; s++) {
shard_[s].SetCapacity(per_shard); shard_[s].SetCapacity(per_shard);
} }
} }
@ -337,6 +338,9 @@ Cache* NewLRUCache(size_t capacity) {
} }
Cache* NewLRUCache(size_t capacity, int numShardBits) { Cache* NewLRUCache(size_t capacity, int numShardBits) {
if (numShardBits >= 20) {
return NULL; // the cache cannot be sharded into too many fine pieces
}
return new ShardedLRUCache(capacity, numShardBits); return new ShardedLRUCache(capacity, numShardBits);
} }

Loading…
Cancel
Save