-
Notifications
You must be signed in to change notification settings - Fork 23.7k
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
Improve performance issue with large number of groups #13957
Conversation
937ec64
to
4b481ad
Compare
Ansible excessively checks the file system for the potential presence of `group_vars` and `host_vars` files. For large numbers of groups this leads to combinatorial performance issues. This commit generates a set of group_vars and host_vars filenames using `os.listdir()` in every possible location and then checks against the sets before making a stat of the file system. Also included in this commit is caching of the base directory lookup for the inventory.
4b481ad
to
063e037
Compare
cc @srvg |
First test of this PR shows me an improvement in parse time around 10-20% - compared to the parent commit. I don't have as many groups as @towolf however, but the difference is real enough. |
We have prepared test case which is structurally identical to our live inventory (just sanitized the json with random strings, cf issue #13956). If you need "more pathological" test data check out the repo: |
@jimi-c any chance we see this before the next freeze? |
@bcoca maybe you could chime in here as well? We'd really love to have this in before stable2.1 is released as Ansible 2.1. |
I did a little bit of profiling with this patch against the test data (git@github.com:towolf/ansible-large-inventory-testcase.git) and tried a few tweaks of my own at https://github.com/alikins/ansible/tree/inventory_profiling The code in this (pr #13957) makes the most difference. Running the test case mentioned above went from ~15 seconds to around 2 seconds.
|
I pushed some SVG flamegraphs of before after to https://github.com/alikins/ansible/tree/inventory_profiling/images (though github doesn't seem to want to display them...) |
Thanks for the corroboration of my findings, @alikins. Do the tweaks you mention work in conjunction with my own? Do you have them separated out as a patch or branch somewhere? Your graphs somehow contain stuff that looks like javascript and text and not SVG graphics. |
Oh, indeed. Did something weird uploading those. Should be fixed now. before: http://alikins.github.io/ansible/images/playbook-inventory-flame.svg after: http://alikins.github.io/ansible/images/playbook-inventory-flame-with-fixes-finer.svg |
Another note about the graphs that isn't obvious. The total time for the first one was in the 12-15s range, while the total time for the second one was in the 1-2s range. (The second graph was ran with higher sampling rate...) |
Ansible excessively checks the file system for the potential presence of `group_vars` and `host_vars` files. For large numbers of groups this leads to combinatorial performance issues. This commit generates a set of group_vars and host_vars filenames using `os.listdir()` in every possible location and then checks against the sets before making a stat of the file system. Also included in this commit is caching of the base directory lookup for the inventory.
I added a comment to 328b423, but wanted to speak up in this PR as well. The commit introduces a breaking change that prevents Ansible from looking in the working directory for group_vars and host_vars. |
@brandond ansible is NOT supposed to look in the working directory, ONLY in the directories in which the inventory and the playbook reside |
@bcoca there must have been a regression introduced at some point then. I started using Ansible fairly recently (2.1) and have structured my workspace such that the top-level directory isn't cluttered with playbooks. If there's a better pattern for keeping a clean top-level folder structure, I'm all ears. I can provide a strace of the group_vars lookup before and after that commit to show that it was indeed checking the working dir; this stopped working after I updated from git, and a bisect isolated the issue to that commit. |
if it was checking it at any point, it was a bug, not a feature, I tested with 1.9 and 2.1 and it behaves in both as I describe, so i'm guessing the bug was introduces somewhere in 2.0 due to the rewrite. |
I just tested branches stable-1.9, stable-2.0.0.1, and stable-2.1.1. All stable releases starting with 2.0 have checked the working directory. Documented or not, this is a breaking change that disables functionality that folks may have depended on working for the last two stable releases. |
I can even tell you why it was doing that. The Inventory class This is demonstrated by adding the following patch to stable-2.1.1:
Gives this result:
|
If it's got to be this way, there should probably be a warning in the 2.2 release notes to the effect that paths that were searched in 2.0 and 2.1 will no longer be checked. |
Ansible excessively checks the file system for the potential presence of
group_vars and host_vars files.
For large numbers of groups this leads to combinatorial performance
issues.
This commit generates a set of group_vars and host_vars filenames for
every possible location and then checks against the sets before making a
stat of the file system.
Also included in this commit is caching of the base directory lookup
for the inventory.
related to issue #13956