Arrow CSV reader peak memory is very large
- Dominant language
- Scala
- Stars
- 1.6k
- Forks
- 657
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 85
Description
### Backend
VL (Velox)
### Bug description
When reading large CSV files, for example, when a single CSV file in a table is 300M, the peak memory usage of arrow memory pool during single-threaded reading can reach 500M. If the CSV is 2G, the peak memory usage can also increase to 1.7G. It looks like there is no memory leak, but the peak memory usage is very high.
From the code of Arrow Dataset, it seems that we are using the Streaming reader, theoretically the memory consumption may not increase proportionally with the size of the CSV file.
I have added some codes in the release method of ArrowNativeMemoryPool to check the peak memory.
```java
@Override
public void release() throws Exception {
System.out.println("peak=" + listener.peak() +", current=" + listener.current());
if (arrowPool.getBytesAllocated() != 0) {
LOGGER.warn(
String.format(
"Arrow pool still reserved non-zero bytes, "
+ "which may cause memory leak, size: %s. ",
Utils.bytesToString(arrowPool.getBytesAllocated())));
}
arrowPool.close();
}
```
I also added some logs in arrow codes to check the peak memory.
```c++
Result CsvFileFormat::ScanBatchesAsync(
const std::shared_ptr& scan_options,
const std::shared_ptr& file) const {
auto this_ = checked_pointer_cast(shared_from_this());
auto source = file->source();
auto reader_fut =
OpenReaderAsync(source, *this, scan_options, ::arrow::internal::GetCpuThreadPool());
auto generator = GeneratorFromReader(std::move(reader_fut), scan_options->batch_size);
WRAP_ASYNC_GENERATOR_WITH_CHILD_SPAN(
generator, "arrow::dataset::CsvFileFormat::ScanBatchesAsync::Next");
std::cout << "memory=" << default_memory_pool()->bytes_allocated() << ", max=" << default_memory_pool()->max_memory() << std::endl;
return generator;
}
```
### Spark version
None
### Spark configurations
_No response_
### System information
_No response_
### Relevant logs
_No response_
Contributor guide
Research direction
Start by reviewing ArrowNativeMemoryPool.release and the Arrow dataset entry point CsvFileFormat::ScanBatchesAsync, including OpenReaderAsync and GeneratorFromReader. Reproduce the reported peak-memory measurements with large CSV input and compare current and peak allocations during single-threaded streaming reads. Done means the cause of the disproportionate peak usage is identified and covered by an appropriate regression test or measurement.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, java
- Domain
- backend, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100