-
Notifications
You must be signed in to change notification settings - Fork 8
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
Fix RequestLoggerController concurrency issues #167
Conversation
@@ -146,7 +147,7 @@ public static String eventId(Instant timestamp, long requestNumber, EventType ev | |||
public RequestLoggerController(TrinoAwsProxyConfig trinoAwsProxyConfig) | |||
{ | |||
// *2 because we log request/response | |||
saveQueue = EvictingQueue.create(trinoAwsProxyConfig.getRequestLoggerSavedQty() * 2); | |||
saveQueue = Queues.synchronizedQueue(EvictingQueue.create(trinoAwsProxyConfig.getRequestLoggerSavedQty() * 2)); |
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 isn't ideal. This will introduce a lot of synchronization. We should find a better solution.
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.
Initially I was favouring a custom implementation of a ConcurrentLinkedQueue with a FIFO eviction policy. I've posted an alternative solution in the PR description.
But running a performance test, the Java synchronisation libraries performed much better maybe due to inbuilt optimisations. I'm good with either solutions. WDYT ?
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.
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.
Sorry I missed the comment. Sync is probably the best solution. Let's go with that.
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.
I agree, I trust the Guava implementation
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.
I think this is fine, and if we observe a performance penalty we can reconsider our options.
Since we disable the requestlogger entirely if the quantity is set to zero, there's an easy way to avoid performance issues if people run into problems after deployment. (that's of course not ideal and we should fix it if it happens, just saying there's an easy rollback)
Fixed #165 @pranavr12 could you please rename the commit to "Fix RequestLoggerController concurrency issues" |
There seems issues with threads on this line in aws-proxy - https://github.com/trinodb/aws-proxy/blob/main/trino-aws-proxy/src/main/java/io/trino/aws/proxy/server/rest/RequestLoggerController.java#L307
Its using EvictingQueue which is not thread-safe.
This PR makes EvictingQueue synchronised by adding a wrapper. Alternatively, we could have used a custom implementation of ConcurrentLinkedQueue (non-blocking, thread safe, natively unbounded) with a FIFO policy. The code would look something like this:
I did a performance test on my local for adding elements into in the queue (16k threads, 50 ops per thread, 100k queue size). The synchronised version of EvictingQueue performed consistently better than the custom implementation. So, decided to go with the synchronised version