From d13503fd0b623d12ce4e394d91bbaedc0aa42407 Mon Sep 17 00:00:00 2001 From: akvlad Date: Mon, 26 Aug 2024 15:46:24 +0300 Subject: [PATCH 1/2] chunking on pprof merge request --- pyroscope/pprof-bin/pkg/pprof_bin.d.ts | 7 ++- pyroscope/pprof-bin/pkg/pprof_bin.js | 20 +++++-- pyroscope/pprof-bin/pkg/pprof_bin_bg.wasm | Bin 225258 -> 226747 bytes .../pprof-bin/pkg/pprof_bin_bg.wasm.d.ts | 3 +- pyroscope/pprof-bin/src/lib.rs | 42 +++++++++++-- pyroscope/pyroscope.js | 56 ++++++++++++++---- pyroscope/render_diff.js | 2 +- 7 files changed, 103 insertions(+), 27 deletions(-) diff --git a/pyroscope/pprof-bin/pkg/pprof_bin.d.ts b/pyroscope/pprof-bin/pkg/pprof_bin.d.ts index ccbddd41..39e35601 100644 --- a/pyroscope/pprof-bin/pkg/pprof_bin.d.ts +++ b/pyroscope/pprof-bin/pkg/pprof_bin.d.ts @@ -26,10 +26,15 @@ export function diff_tree(id1: number, id2: number, sample_type: string): Uint8A */ export function export_tree(id: number, sample_type: string): Uint8Array; /** +* @param {number} id * @param {Uint8Array} payload +*/ +export function merge_trees_pprof(id: number, payload: Uint8Array): void; +/** +* @param {number} id * @returns {Uint8Array} */ -export function export_trees_pprof(payload: Uint8Array): Uint8Array; +export function export_trees_pprof(id: number): Uint8Array; /** * @param {number} id */ diff --git a/pyroscope/pprof-bin/pkg/pprof_bin.js b/pyroscope/pprof-bin/pkg/pprof_bin.js index 25da605f..e9a9781b 100644 --- a/pyroscope/pprof-bin/pkg/pprof_bin.js +++ b/pyroscope/pprof-bin/pkg/pprof_bin.js @@ -177,20 +177,28 @@ module.exports.export_tree = function(id, sample_type) { }; /** +* @param {number} id * @param {Uint8Array} payload +*/ +module.exports.merge_trees_pprof = function(id, payload) { + const ptr0 = passArray8ToWasm0(payload, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.merge_trees_pprof(id, ptr0, len0); +}; + +/** +* @param {number} id * @returns {Uint8Array} */ -module.exports.export_trees_pprof = function(payload) { +module.exports.export_trees_pprof = function(id) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArray8ToWasm0(payload, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - wasm.export_trees_pprof(retptr, ptr0, len0); + wasm.export_trees_pprof(retptr, id); var r0 = getInt32Memory0()[retptr / 4 + 0]; var r1 = getInt32Memory0()[retptr / 4 + 1]; - var v2 = getArrayU8FromWasm0(r0, r1).slice(); + var v1 = getArrayU8FromWasm0(r0, r1).slice(); wasm.__wbindgen_free(r0, r1 * 1, 1); - return v2; + return v1; } finally { wasm.__wbindgen_add_to_stack_pointer(16); } diff --git a/pyroscope/pprof-bin/pkg/pprof_bin_bg.wasm b/pyroscope/pprof-bin/pkg/pprof_bin_bg.wasm index 6380006b4212600682e3b878038e4d8b20ecde61..930457c9151072047f91add8c07319105bd3352d 100644 GIT binary patch delta 57041 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 IuRQO601Nix*Z=?k delta 55213 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 diff --git a/pyroscope/pprof-bin/pkg/pprof_bin_bg.wasm.d.ts b/pyroscope/pprof-bin/pkg/pprof_bin_bg.wasm.d.ts index 6dc10bc2..8947ed29 100644 --- a/pyroscope/pprof-bin/pkg/pprof_bin_bg.wasm.d.ts +++ b/pyroscope/pprof-bin/pkg/pprof_bin_bg.wasm.d.ts @@ -5,7 +5,8 @@ export function merge_prof(a: number, b: number, c: number, d: number, e: number export function merge_tree(a: number, b: number, c: number, d: number, e: number): void; export function diff_tree(a: number, b: number, c: number, d: number, e: number): void; export function export_tree(a: number, b: number, c: number, d: number): void; -export function export_trees_pprof(a: number, b: number, c: number): void; +export function merge_trees_pprof(a: number, b: number, c: number): void; +export function export_trees_pprof(a: number, b: number): void; export function drop_tree(a: number): void; export function init_panic_hook(): void; export function __wbindgen_malloc(a: number, b: number): number; diff --git a/pyroscope/pprof-bin/src/lib.rs b/pyroscope/pprof-bin/src/lib.rs index c07523a7..a22a99ab 100644 --- a/pyroscope/pprof-bin/src/lib.rs +++ b/pyroscope/pprof-bin/src/lib.rs @@ -77,6 +77,7 @@ struct Tree { sample_types: Vec, max_self: Vec, nodes_num: i32, + pprof: Profile, } impl Tree { @@ -357,6 +358,7 @@ fn upsert_tree(ctx: &mut HashMap>, id: u32, sample_types: Vec usize { let res = read_uleb128(&self.bytes[self.offs..]); self.offs += res.1; - res.0 + res.0.clone() } fn read_string(&mut self) -> String { @@ -423,6 +425,24 @@ impl TrieReader { } res } + fn read_blob(&mut self) -> &[u8] { + let size = self.read_size(); + let string = &self.bytes[self.offs..self.offs + size]; + self.offs += size; + string + } + fn read_blob_list(&mut self) -> Vec<&[u8]> { + let mut res = Vec::new(); + while self.offs < self.bytes.len() { + let uleb = read_uleb128(&self.bytes[self.offs..]); + self.offs += uleb.1; + let _size = uleb.0; + let string = &self.bytes[self.offs..self.offs + _size]; + self.offs += _size; + res.push(string); + } + res + } /*fn end(&self) -> bool { self.offs >= self.bytes.len() }*/ @@ -917,11 +937,15 @@ pub fn export_tree(id: u32, sample_type: String) -> Vec { } #[wasm_bindgen] -pub fn export_trees_pprof(payload: &[u8]) -> Vec { +pub fn merge_trees_pprof(id: u32, payload: &[u8]) { let p = panic::catch_unwind(|| { + let mut ctx = CTX.lock().unwrap(); + upsert_tree(&mut ctx, id, vec![]); + let mut tree = ctx.get_mut(&id).unwrap().lock().unwrap(); let mut reader = TrieReader::new(payload); - let bin_profs = reader.read_blob_vec(); + let bin_profs = reader.read_blob_list(); let mut merger = merge::ProfileMerge::new(); + merger.merge(&mut tree.pprof); for bin_prof in bin_profs { if bin_prof.len() >= 2 && bin_prof[0] == 0x1f && bin_prof[1] == 0x8b { let mut decompressed = Vec::new(); @@ -936,14 +960,22 @@ pub fn export_trees_pprof(payload: &[u8]) -> Vec { } let res = merger.profile(); - res.encode_to_vec() + tree.pprof = res; }); match p { - Ok(res) => return res, + Ok(_) => {} Err(err) => panic!("{:?}", err), } } +#[wasm_bindgen] +pub fn export_trees_pprof(id: u32) -> Vec { + let mut ctx = CTX.lock().unwrap(); + upsert_tree(&mut ctx, id, vec![]); + let tree = ctx.get_mut(&id).unwrap().lock().unwrap(); + tree.pprof.encode_to_vec() +} + #[wasm_bindgen] pub fn drop_tree(id: u32) { let mut ctx = CTX.lock().unwrap(); diff --git a/pyroscope/pyroscope.js b/pyroscope/pyroscope.js index 57609adc..c635b99b 100644 --- a/pyroscope/pyroscope.js +++ b/pyroscope/pyroscope.js @@ -19,7 +19,7 @@ const { HISTORY_TIMESPAN } = require('./shared') const settings = require('./settings') -const { mergeStackTraces } = require('./merge_stack_traces') +const { mergeStackTraces, newCtxIdx } = require('./merge_stack_traces') const { selectSeriesImpl } = require('./select_series') const render = require('./render') @@ -166,25 +166,55 @@ const selectMergeProfile = async (req, res) => { const withIdxReq = (new Sql.With('idx', idxReq, !!clusterName)) const mainReq = (new Sql.Select()) .with(withIdxReq) - .select([new Sql.Raw('groupArray(payload)'), 'payload']) + .select([new Sql.Raw('payload'), 'payload']) .from([`${DATABASE_NAME()}.profiles${dist}`, 'p']) .where(Sql.And( new Sql.In('p.fingerprint', 'IN', new Sql.WithReference(withIdxReq)), Sql.Gte('p.timestamp_ns', new Sql.Raw(`${fromTimeSec}000000000`)), Sql.Lt('p.timestamp_ns', new Sql.Raw(`${toTimeSec}000000000`)))) - - const profiles = await clickhouse.rawRequest(mainReq.toString() + ' FORMAT RowBinary', - null, - DATABASE_NAME(), - { - responseType: 'arraybuffer' - }) - const binData = Uint8Array.from(profiles.data) - + .orderBy(new Sql.Raw('timestamp_ns')) + const approxReq = (new Sql.Select()) + .select( + [new Sql.Raw('sum(length(payload))'), 'size'], + [new Sql.Raw('count()'), 'count'] + ) + .from([new Sql.Raw('(' + mainReq.toString() + ')'), 'main']) + console.log('!!!!!' + approxReq.toString() + ' FORMAT JSON') + const approx = await clickhouse.rawRequest( + approxReq.toString() + ' FORMAT JSON', null, DATABASE_NAME() + ) + const approxData = approx.data.data[0] + logger.debug(`Approximate size: ${approxData.size} bytes, profiles count: ${approxData.count}`) + const chunksCount = Math.max(Math.ceil(approxData.size / (50 * 1024)), 1) + logger.debug(`Request is processed in: ${chunksCount} chunks`) + const chunkSize = Math.ceil(approxData.count / chunksCount) + const promises = [] require('./pprof-bin/pkg/pprof_bin').init_panic_hook() + let processNs = BigInt(0) const start = process.hrtime.bigint() - const response = pprofBin.export_trees_pprof(binData) - logger.debug(`Pprof export took ${process.hrtime.bigint() - start} nanoseconds`) + const ctx = newCtxIdx() + for (let i = 0; i < chunksCount; i++) { + promises.push((async (i) => { + logger.debug(`Chunk ${i}: ${mainReq.toString() + ` LIMIT ${chunkSize} OFFSET ${i * chunkSize} FORMAT RowBinary`}`) + const profiles = await clickhouse.rawRequest(mainReq.toString() + ` LIMIT ${chunkSize} OFFSET ${i * chunkSize} FORMAT RowBinary`, + null, + DATABASE_NAME(), + { + responseType: 'arraybuffer' + }) + const binData = Uint8Array.from(profiles.data) + const start = process.hrtime.bigint() + pprofBin.merge_trees_pprof(ctx, binData) + const end = process.hrtime.bigint() + processNs += end - start + })(i)) + } + await Promise.all(promises) + const response = pprofBin.export_trees_pprof(ctx) + const end = process.hrtime.bigint() + + logger.debug(`Pprof merge took ${processNs} nanoseconds`) + logger.debug(`Pprof load + merge took ${end - start} nanoseconds`) return res.code(200).send(Buffer.from(response)) } diff --git a/pyroscope/render_diff.js b/pyroscope/render_diff.js index 8d27ac62..e8be19cd 100644 --- a/pyroscope/render_diff.js +++ b/pyroscope/render_diff.js @@ -12,7 +12,7 @@ const renderDiff = async (req, res) => { parseParams(req.query.leftQuery, req.query.leftFrom, req.query.leftUntil); const [rightQuery, rightFromTimeSec, rightToTimeSec] = parseParams(req.query.rightQuery, req.query.rightFrom, req.query.rightUntil); - if (leftQuery.typeId != rightQuery.typeId) { + if (leftQuery.typeId !== rightQuery.typeId) { res.code(400).send('Different type IDs') return } From b6a4c3ff670ab1bee6b81d67a0bbb03068cb1977 Mon Sep 17 00:00:00 2001 From: akvlad Date: Mon, 26 Aug 2024 15:46:49 +0300 Subject: [PATCH 2/2] chunking on pprof merge request --- pyroscope/pyroscope.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyroscope/pyroscope.js b/pyroscope/pyroscope.js index c635b99b..58945cb9 100644 --- a/pyroscope/pyroscope.js +++ b/pyroscope/pyroscope.js @@ -185,7 +185,7 @@ const selectMergeProfile = async (req, res) => { ) const approxData = approx.data.data[0] logger.debug(`Approximate size: ${approxData.size} bytes, profiles count: ${approxData.count}`) - const chunksCount = Math.max(Math.ceil(approxData.size / (50 * 1024)), 1) + const chunksCount = Math.max(Math.ceil(approxData.size / (50 * 1024 * 1024)), 1) logger.debug(`Request is processed in: ${chunksCount} chunks`) const chunkSize = Math.ceil(approxData.count / chunksCount) const promises = []