-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fstore: hold more than 64 files #4680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
if (delete == FLB_TRUE) { | ||
cio_stream_delete(stream->stream); | ||
|
||
/* remove stream files from fstore files_up up list */ | ||
mk_list_foreach(head, &stream->files) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the entry fsf
will be removed from the list, it will generate a corruption with other linked elements, you have you use mk_list_foreach_safe()
instead mk_list_foreach()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
files_up_remove removes file from files_up
list in fstore. mk_list_foreach enumerates files
list in stream. I think mk_list_foreach is okay in this case because files list not modified, though can replace with mk_list_foreach_safe()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, is this because of multithreading, @edsiper? I didn't consider that.
@@ -64,7 +64,7 @@ void cb_all() | |||
ret = stat(FSF_STORE_PATH "/abc/example.txt", &st_data); | |||
TEST_CHECK(ret == 0); | |||
|
|||
ret = flb_fstore_file_append(fsf, "fluent-bit\n", 11); | |||
ret = flb_fstore_file_append(fs, fsf, "fluent-bit\n", 11); | |||
TEST_CHECK(ret == 0); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please extend the fstore.c unit test to try to reproduce the issue you were facing initially
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sound good. Will add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a test!
Get the following errors without the patch:
[2022/02/11 04:47:22] [error] [fstore] [cio file] file is not mmap()ed: abc:files-round_2-65.txt
[2022/02/11 04:47:22] [error] [fstore] could not write data to file files-round_2-65.txt
fstore.c:172: Check ret == 0... failed
fstore.c:177: Check memcmp(out_buf, "fluent-bit-3\n", 13) == 0... failed
fstore.c:178: Check out_size == 13... failed
fstore.c:169: Check ret == 0... failed
[2022/02/11 04:47:22] [error] [fstore] [cio file] file is not mmap()ed: abc:files-round_2-66.txt
[2022/02/11 04:47:22] [error] [fstore] could not write data to file files-round_2-66.txt
fstore.c:172: Check ret == 0... failed
fstore.c:177: Check memcmp(out_buf, "fluent-bit-3\n", 13) == 0... failed
fstore.c:178: Check out_size == 13... failed
fstore.c:169: Check ret == 0... failed
[2022/02/11 04:47:22] [error] [fstore] [cio file] file is not mmap()ed: abc:files-round_2-67.txt
[2022/02/11 04:47:22] [error] [fstore] could not write data to file files-round_2-67.txt
...
fstore.c:193: Check out_size == 11+13... failed
FAILED: 1 of 2 unit tests has failed.
With the patch, the following is output showing success:
[ec2-user@ip-172-31-30-69 bin]$ /home/ec2-user/fala-forks/fluent-bit/build/bin/flb-it-fstore
Test all... [2022/02/11 04:50:17] [ info] [fstore] created root path /tmp/flb-fstore
===== FSTORE DUMP =====
- stream: abc
abc/example.txt (up)
[ OK ]
Test many_files... [2022/02/11 04:50:17] [ info] [fstore] created root path /tmp/flb-fstore
[2022/02/11 04:50:17] [ info] [fstore] created root path /tmp/flb-fstore
[2022/02/11 04:50:17] [ info] [fstore] created root path /tmp/flb-fstore
[2022/02/11 04:50:17] [ info] [fstore] created root path /tmp/flb-fstore
[ OK ]
SUCCESS: All unit tests have passed.
|
9b3fea6
to
2fd4384
Compare
Signed-off-by: Matthew Fala <falamatt@amazon.com>
2fd4384
to
c01c60a
Compare
@@ -358,6 +358,7 @@ static int mmap_file(struct cio_ctx *ctx, struct cio_chunk *ch, size_t size) | |||
|
|||
cio_log_debug(ctx, "%s:%s adjusting size OK", ch->st->name, ch->name); | |||
} | |||
cf->alloc_size = size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@edsiper alloc_size may need to reflect the true size of the file here, not the size rounded up. Trying to append to file does not write through when alloc_size misrepresents the true filesize because file resize not detected.
File resize needed on chunk_down -> chunk_up -> append because chunk_down truncates file extra space, chunk_up restores file with alloc_size misrepresenting true filesize (rounded non-truncated filesize) and append expects the file to be non-truncated size and the write fails.
There are several solution options I tried which all work (the tests fail if none of the following are implemented)
- Round up only mmap (implemented)
- alloc_size not rounded up and represents true file size
- Move
alloc_size = size
above round up. This keeps mmap length still a multiple of page size, but larger than true filesize
- Don't round up alloc_size or mmap (another option -- Preferred but needs confirmation)
- Just delete the following ROUND_UP(size, ctx->page_size). mmap length is now the true length of the file.
- This seems the most straightforward but I don't know if you want mmap to always allocate in increments of page size for some reason.
- Actually resize the file (another option)
- A file resize needed at least once before append since file truncated on let down.
- Not needed if alloc_size is set since append would detect resize needed and will resize and remap.
- Lazy may be better for cases with only read and no append
/* add the following to the if (fs_size > 0) { ... } block */
/* Round up filesize to allow for appends */
size = ROUND_UP(size, ctx->page_size);
ret = cio_file_fs_size_change(cf, size);
Added tests! Merge requires change to chunkio dep. Please see notes above. |
Signed-off-by: falamatt@amazon.com <falamatt@amazon.com>
Signed-off-by: falamatt@amazon.com <falamatt@amazon.com>
c01c60a
to
0df0300
Compare
return 0; | ||
} | ||
|
||
void test_chunkio_up_down_up_append() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case displays the issue with chunk io append after up > down > up > append.
in order to merge this, please submit the chunkio fix/PR to https://github.com/edsiper/chunkio first, then we do the sync here. |
PR'd to chunkio: fluent/chunkio#80. |
Please hold off on merging till the conversation on thread safety is settled. |
re: threading... each context creator is responsible to protect multiple readers/writers. |
@matthewfala is this ready to go besides the threading concerns ? |
Hi @edsiper, This PR was heavily tested a while ago, however it looks like Leonardo and the team resolved this issues in the following PR using a somewhat simpler method. If there are more than 64 files, Leonardo's pr will just open a 65th file via a force, do the operation and close the file. My PR closes the least recently used file, and opens a new 64th file. I think we should keep this PR open and switch to it if you find a common use case where file access patterns are biased toward a small set of files, with many infrequently accessed files. In this case, my solution will perform better. In the case where there's just a bunch of infrequently accessed files (only written to once), both solutions perform equally poorly. |
@PettitWesley for visibility |
Signed-off-by: Matthew Fala falamatt@amazon.com
FStore - Store More Than 64 Files
FStore is used to store data locally in files. There is a limitation of 64 files which FStore can store. This is due to a configuration in chunkio that limits memory mapped files to 64. It would be nice to have more than 64 files held/tracked in FStore at a given time.
The easier way to do this would be to increasing the chunkio memory map limit to some arbitrary large number. However this seems to be against the design put forth by chunkio where a small number of files should be memory mapped (or up) and let down when not needed
This PR explores the alternate route of adding and removing mapped files strategically to keep the number of memory mapped files always <= 64
This PR implements a caching system for memory mapped files. Files that are least frequently accessed through fstore are let down after the 64 file limit has been reached. These files are brought up by fstore when demanded.
The cache is a linked list of memory mapped "up" files which, on initialization, is initialized to a list of files brought up by chunkio. This list is maintained throughout fstore lifecycle. On file access, the linked list is rearranged to reference the newly accessed file first. On loading the 65th file, the last file in the cache list is put down and the 65th file is brought up, keeping 64 files in memory.
Enter
[N/A]
in the box, if an item is not applicable to your change.Testing
Before we can approve your change; please submit the following in a comment:
This problem is impacting clients of S3 plugin who have more than 64 log files that will eventually upload.
Steps to reproduce problem and view solution:
Before the patch: Errors should be available in fluent-bit logs. S3 will only be able to upload 64 files. The remaining 1000-64 files are not uploaded due to fstore limitations.
After the patch: No errors are shown in the logs. S3 will be able to upload 65+ files. Tested with 1000 and 5000 files. Upload successful. No errors.
If this is a change to packaging of containers or native binaries then please confirm it works for all targets.
Documentation
Backporting
Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.