Hi All,
I am having an issue where I make a simple find query and the first attempt for particular items might take 20 to 30 seconds, but then if I query for the same items it is under half a second. Pretty sure this is due to caching but the initial query taking so long is causing be quite a lot of grief.
I am aware the first query is likely being pulled from disk, but I don’t believe it should take as long as it does given there is at most about 10K documents for any particular indexed item. So even if I only filtered on the indexed item for all records it should only pull in a reasonably small set.
I am using fairly high spec VMs backed by an enterprise SSD storage data centre.
DB is split across 4 shards each having 2 RS+Arb. 8CPU/32GB/3TB ea
Using 2 mongos. 4CPU/16GB ea
[mongos] ni4cc2> db.data_events.getIndexes()
[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { 'commonEventHeader.eventFields.msisdn': 'hashed' },
name: 'commonEventHeader.eventFields.msisdn_hashed'
},
{
v: 2,
key: { start_epoch_microsec: 1 },
name: 'start_epoch_microsec_1',
expireAfterSeconds: 3024000
}
]
[mongos] ni4cc2> db.data_events.getShardDistribution()
Shard ni4cc2-rs4 at ni4cc2-rs4/dbnode4:27050,dbnode8:27051
{
data: '2636.88GiB',
docs: 543863130,
chunks: 24672,
'estimated data per chunk': '109.44MiB',
'estimated docs per chunk': 22043
}
---
Shard ni4cc2-rs3 at ni4cc2-rs3/dbnode3:27040,dbnode7:27041
{
data: '3970.52GiB',
docs: 1194578619,
chunks: 24672,
'estimated data per chunk': '164.79MiB',
'estimated docs per chunk': 48418
}
---
Shard ni4cc2-rs1 at ni4cc2-rs1/dbnode1:27020,dbnode5:27021
{
data: '2640.67GiB',
docs: 544733199,
chunks: 24673,
'estimated data per chunk': '109.59MiB',
'estimated docs per chunk': 22078
}
---
Shard ni4cc2-rs2 at ni4cc2-rs2/dbnode2:27030,dbnode6:27031
{
data: '2633.88GiB',
docs: 543462431,
chunks: 24672,
'estimated data per chunk': '109.31MiB',
'estimated docs per chunk': 22027
}
---
Totals
{
data: '2.6368893047463394e+42GiB',
docs: 2826637379,
chunks: 98689,
'Shard ni4cc2-rs4': [
'0 % data',
'19.24 % docs in cluster',
'5KiB avg obj size on shard'
],
'Shard ni4cc2-rs3': [
'0 % data',
'42.26 % docs in cluster',
'3KiB avg obj size on shard'
],
'Shard ni4cc2-rs1': [
'0 % data',
'19.27 % docs in cluster',
'5KiB avg obj size on shard'
],
'Shard ni4cc2-rs2': [
'0 % data',
'19.22 % docs in cluster',
'5KiB avg obj size on shard'
]
}
[mongos] ni4cc2> db.data_events.explain("allPlansExecution").find({
... "commonEventHeader.eventFields.msisdn":'8stringOFnums8',
... "start_epoch_microsec": {
..... "$gte": new Date("2022-10-09T00:00:00+10:00"),
..... "$lt" : new Date("2022-10-11T00:00:00+10:00")
..... }
... })
{
queryPlanner: {
mongosPlannerVersion: 1,
winningPlan: {
stage: 'SINGLE_SHARD',
shards: [
{
shardName: 'ni4cc2-rs3',
connectionString: 'ni4cc2-rs3/dbnode3:27040,dbnode7:27041',
serverInfo: {
host: '1c921c1e4ec1',
port: 27017,
version: '6.0.2',
gitVersion: '94fb7dfc8b974f1f5343e7ea394d0d9deedba50e'
},
namespace: 'ni4cc2.data_events',
indexFilterSet: false,
parsedQuery: {
'$and': [
{
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
{
start_epoch_microsec: { '$lt': ISODate("2022-10-10T14:00:00.000Z") }
},
{
start_epoch_microsec: { '$gte': ISODate("2022-10-08T14:00:00.000Z") }
}
]
},
queryHash: 'C12E761C',
planCacheKey: '3E585050',
maxIndexedOrSolutionsReached: false,
maxIndexedAndSolutionsReached: false,
maxScansToExplodeReached: false,
winningPlan: {
stage: 'FETCH',
filter: {
'$and': [
{
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
{
start_epoch_microsec: { '$lt': ISODate("2022-10-10T14:00:00.000Z") }
},
{
start_epoch_microsec: { '$gte': ISODate("2022-10-08T14:00:00.000Z") }
}
]
},
inputStage: {
stage: 'IXSCAN',
keyPattern: { 'commonEventHeader.eventFields.msisdn': 'hashed' },
indexName: 'commonEventHeader.eventFields.msisdn_hashed',
isMultiKey: false,
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
'commonEventHeader.eventFields.msisdn': [ '[3554060079612239688, 3554060079612239688]' ]
}
}
},
rejectedPlans: [
{
stage: 'FETCH',
filter: {
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
inputStage: {
stage: 'IXSCAN',
keyPattern: { start_epoch_microsec: 1 },
indexName: 'start_epoch_microsec_1',
isMultiKey: false,
multiKeyPaths: { start_epoch_microsec: [] },
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
start_epoch_microsec: [
'[new Date(1665237600000), new Date(1665410400000))'
]
}
}
}
]
}
]
}
},
executionStats: {
nReturned: 0,
executionTimeMillis: 22,
totalKeysExamined: 6,
totalDocsExamined: 6,
executionStages: {
stage: 'SINGLE_SHARD',
nReturned: 0,
executionTimeMillis: 22,
totalKeysExamined: 6,
totalDocsExamined: 6,
totalChildMillis: Long("21"),
shards: [
{
shardName: 'ni4cc2-rs3',
executionSuccess: true,
nReturned: 0,
executionTimeMillis: 21,
totalKeysExamined: 6,
totalDocsExamined: 6,
executionStages: {
stage: 'FETCH',
filter: {
'$and': [
{
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
{
start_epoch_microsec: { '$lt': ISODate("2022-10-10T14:00:00.000Z") }
},
{
start_epoch_microsec: { '$gte': ISODate("2022-10-08T14:00:00.000Z") }
}
]
},
nReturned: 0,
executionTimeMillisEstimate: 11,
works: 8,
advanced: 0,
needTime: 6,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 1,
docsExamined: 6,
alreadyHasObj: 0,
inputStage: {
stage: 'IXSCAN',
nReturned: 6,
executionTimeMillisEstimate: 1,
works: 7,
advanced: 6,
needTime: 0,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 1,
keyPattern: { 'commonEventHeader.eventFields.msisdn': 'hashed' },
indexName: 'commonEventHeader.eventFields.msisdn_hashed',
isMultiKey: false,
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
'commonEventHeader.eventFields.msisdn': [ '[3554060079612239688, 3554060079612239688]' ]
},
keysExamined: 6,
seeks: 1,
dupsTested: 0,
dupsDropped: 0
}
},
allPlansExecution: [
{
nReturned: 0,
executionTimeMillisEstimate: 11,
totalKeysExamined: 6,
totalDocsExamined: 6,
score: 2.0002,
executionStages: {
stage: 'FETCH',
filter: {
'$and': [
{
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
{
start_epoch_microsec: { '$lt': ISODate("2022-10-10T14:00:00.000Z") }
},
{
start_epoch_microsec: { '$gte': ISODate("2022-10-08T14:00:00.000Z") }
}
]
},
nReturned: 0,
executionTimeMillisEstimate: 11,
works: 7,
advanced: 0,
needTime: 6,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 1,
docsExamined: 6,
alreadyHasObj: 0,
inputStage: {
stage: 'IXSCAN',
nReturned: 6,
executionTimeMillisEstimate: 1,
works: 7,
advanced: 6,
needTime: 0,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 1,
keyPattern: { 'commonEventHeader.eventFields.msisdn': 'hashed' },
indexName: 'commonEventHeader.eventFields.msisdn_hashed',
isMultiKey: false,
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
'commonEventHeader.eventFields.msisdn': [ '[3554060079612239688, 3554060079612239688]' ]
},
keysExamined: 6,
seeks: 1,
dupsTested: 0,
dupsDropped: 0
}
}
},
{
nReturned: 0,
executionTimeMillisEstimate: 6,
totalKeysExamined: 7,
totalDocsExamined: 7,
score: 1.0002,
executionStages: {
stage: 'FETCH',
filter: {
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
nReturned: 0,
executionTimeMillisEstimate: 6,
works: 7,
advanced: 0,
needTime: 7,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 0,
docsExamined: 7,
alreadyHasObj: 0,
inputStage: {
stage: 'IXSCAN',
nReturned: 7,
executionTimeMillisEstimate: 2,
works: 7,
advanced: 7,
needTime: 0,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 0,
keyPattern: { start_epoch_microsec: 1 },
indexName: 'start_epoch_microsec_1',
isMultiKey: false,
multiKeyPaths: { start_epoch_microsec: [] },
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
start_epoch_microsec: [
'[new Date(1665237600000), new Date(1665410400000))'
]
},
keysExamined: 7,
seeks: 1,
dupsTested: 0,
dupsDropped: 0
}
}
}
]
}
]
},
allPlansExecution: [
{
shardName: 'ni4cc2-rs3',
allPlans: [
{
nReturned: 0,
executionTimeMillisEstimate: 11,
totalKeysExamined: 6,
totalDocsExamined: 6,
score: 2.0002,
executionStages: {
stage: 'FETCH',
filter: {
'$and': [
{
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
{
start_epoch_microsec: { '$lt': ISODate("2022-10-10T14:00:00.000Z") }
},
{
start_epoch_microsec: { '$gte': ISODate("2022-10-08T14:00:00.000Z") }
}
]
},
nReturned: 0,
executionTimeMillisEstimate: 11,
works: 7,
advanced: 0,
needTime: 6,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 1,
docsExamined: 6,
alreadyHasObj: 0,
inputStage: {
stage: 'IXSCAN',
nReturned: 6,
executionTimeMillisEstimate: 1,
works: 7,
advanced: 6,
needTime: 0,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 1,
keyPattern: { 'commonEventHeader.eventFields.msisdn': 'hashed' },
indexName: 'commonEventHeader.eventFields.msisdn_hashed',
isMultiKey: false,
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
'commonEventHeader.eventFields.msisdn': [ '[3554060079612239688, 3554060079612239688]' ]
},
keysExamined: 6,
seeks: 1,
dupsTested: 0,
dupsDropped: 0
}
}
},
{
nReturned: 0,
executionTimeMillisEstimate: 6,
totalKeysExamined: 7,
totalDocsExamined: 7,
score: 1.0002,
executionStages: {
stage: 'FETCH',
filter: {
'commonEventHeader.eventFields.msisdn': { '$eq': '8stringOFnums8' }
},
nReturned: 0,
executionTimeMillisEstimate: 6,
works: 7,
advanced: 0,
needTime: 7,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 0,
docsExamined: 7,
alreadyHasObj: 0,
inputStage: {
stage: 'IXSCAN',
nReturned: 7,
executionTimeMillisEstimate: 2,
works: 7,
advanced: 7,
needTime: 0,
needYield: 0,
saveState: 1,
restoreState: 1,
isEOF: 0,
keyPattern: { start_epoch_microsec: 1 },
indexName: 'start_epoch_microsec_1',
isMultiKey: false,
multiKeyPaths: { start_epoch_microsec: [] },
isUnique: false,
isSparse: false,
isPartial: false,
indexVersion: 2,
direction: 'forward',
indexBounds: {
start_epoch_microsec: [
'[new Date(1665237600000), new Date(1665410400000))'
]
},
keysExamined: 7,
seeks: 1,
dupsTested: 0,
dupsDropped: 0
}
}
}
]
}
]
},
serverInfo: {
host: '5d950768592c',
port: 27017,
version: '6.0.2',
gitVersion: '94fb7dfc8b974f1f5343e7ea394d0d9deedba50e'
},
serverParameters: {
internalQueryFacetBufferSizeBytes: 104857600,
internalQueryFacetMaxOutputDocSizeBytes: 104857600,
internalLookupStageIntermediateDocumentMaxSizeBytes: 104857600,
internalDocumentSourceGroupMaxMemoryBytes: 104857600,
internalQueryMaxBlockingSortMemoryUsageBytes: 104857600,
internalQueryProhibitBlockingMergeOnMongoS: 0,
internalQueryMaxAddToSetBytes: 104857600,
internalDocumentSourceSetWindowFieldsMaxMemoryBytes: 104857600
},
command: {
find: 'data_events',
filter: {
'commonEventHeader.eventFields.msisdn': '8stringOFnums8',
start_epoch_microsec: {
'$gte': ISODate("2022-10-08T14:00:00.000Z"),
'$lt': ISODate("2022-10-10T14:00:00.000Z")
}
},
lsid: { id: UUID("bcf5d84a-6a4e-49f9-b53b-dd606a732347") },
'$clusterTime': {
clusterTime: Timestamp({ t: 1665616627, i: 347 }),
signature: {
hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
keyId: Long("0")
}
},
'$db': 'ni4cc2',
'$readPreference': { mode: 'secondaryPreferred' }
},
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1665616950, i: 404 }),
signature: {
hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
keyId: Long("0")
}
},
operationTime: Timestamp({ t: 1665616950, i: 402 })
}
I did notice it seems to favor the Hashed index based on the partitioning key. Ignoring the date index.
[mongos] ni4cc2> db.data_events.latencyStats()
[
{
ns: 'ni4cc2.data_events',
shard: 'ni4cc2-rs4',
host: '947f417ee9e7:27017',
localTime: ISODate("2022-10-13T00:40:04.611Z"),
latencyStats: {
reads: { latency: Long("30374180"), ops: Long("351") },
writes: { latency: Long("0"), ops: Long("0") },
commands: { latency: Long("15483"), ops: Long("8") },
transactions: { latency: Long("0"), ops: Long("0") }
}
},
{
ns: 'ni4cc2.data_events',
shard: 'ni4cc2-rs2',
host: '1198a80e3a0d:27017',
localTime: ISODate("2022-10-13T00:40:04.611Z"),
latencyStats: {
reads: { latency: Long("5680449"), ops: Long("306") },
writes: { latency: Long("0"), ops: Long("0") },
commands: { latency: Long("0"), ops: Long("0") },
transactions: { latency: Long("0"), ops: Long("0") }
}
},
{
ns: 'ni4cc2.data_events',
shard: 'ni4cc2-rs1',
host: 'b5b60ccde536:27017',
localTime: ISODate("2022-10-13T00:40:04.612Z"),
latencyStats: {
reads: { latency: Long("14913376"), ops: Long("319") },
writes: { latency: Long("0"), ops: Long("0") },
commands: { latency: Long("0"), ops: Long("0") },
transactions: { latency: Long("0"), ops: Long("0") }
}
},
{
ns: 'ni4cc2.data_events',
shard: 'ni4cc2-rs3',
host: '1c921c1e4ec1:27017',
localTime: ISODate("2022-10-13T00:40:04.611Z"),
latencyStats: {
reads: { latency: Long("541987744"), ops: Long("2957") },
writes: { latency: Long("1531416588"), ops: Long("444521") },
commands: { latency: Long("4452502327"), ops: Long("13") },
transactions: { latency: Long("0"), ops: Long("0") }
}
}
]
[mongos] config> db.chunks.latencyStats()
[
{
ns: 'config.chunks',
host: 'e89bcffaddb9:27017',
localTime: ISODate("2022-10-13T00:44:30.624Z"),
latencyStats: {
reads: { latency: Long("3099752"), ops: Long("3273") },
writes: { latency: Long("0"), ops: Long("0") },
commands: { latency: Long("0"), ops: Long("0") },
transactions: { latency: Long("0"), ops: Long("0") }
}
}
]
I am seeing a lot of IOWait on some nodes with top and vmstat, yet iostat shows not very much and also the data rate for the disks is only around 50MB/s yet it can push upwards of 250MB/s on a file copy.
Also wondered if the config DB was contributing! How much of the chunk distrubution is cached? I don’t see any index on the config database for the partition key, how does the mongos determine the RS?
[mongos] config> db.chunks.getIndexes()
[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { uuid: 1, min: 1 },
name: 'uuid_1_min_1',
unique: true
},
{
v: 2,
key: { uuid: 1, shard: 1, min: 1 },
name: 'uuid_1_shard_1_min_1',
unique: true
},
{
v: 2,
key: { uuid: 1, lastmod: 1 },
name: 'uuid_1_lastmod_1',
unique: true
}
]
I have set the following tuning suggestions, Which didn’t seem to make any difference:
- vm.max_map_count=128000
- transparent_hugepages=never
- transparent_hugepage.defrag=never
- readahead=32
- IO Scheduler=noop
It doesn’t seem to make a difference if I specify date range or not, So I suspect this ties in with the unutilized date index.
Some options I have thought about:
- More ReplicaSets, Perhaps putting 4 replicasets per node for a total of 16
- Splitting the collection up into multiple collections with a two digit hash appended to collection name to simulate internal partitioning. EG: data_events → data_events_[00-ff] then manually hash the msisdn to know which collection to insert or query
Many hours spent already investigating, Appreciate any suggestions on checks, strategies, issues?