如何从 Kestrel 队列中有效获取数据

发布于 2024-11-18 19:46:09 字数 1592 浏览 3 评论 0原文

由于某种原因,我们计划在我们的项目中使用 Kestrel 队列。我们做了一些恶魔,主要问题是如何在低CPU利用率的情况下有效地从队列中获取数据。我们实现的获取方式是,如果从队列中获取数据失败超过 5 次,我们将线程休眠 100 毫秒以降低 CPU 利用率。

while (running) {
            try {
                LoginLogQueueEntry data = kestrelQueue.fetch();
                if (null != data && data.isLegal()) {
                    entryCacheList.add(data); //add the data to the local caceh
                    resetStatus();
                } else {
                    failedCount++;
                    //if there is no data in the kestrel and the local cache is not empty, insert the data into mysql database
                    if (failedCount == 1 && !entryCacheList.isEmpty()) {
                        resetStatus();
                        insertLogList(entryCacheList); // insert current data into database
                        entryCacheList.clear(); //empty local cache
                    }

                    if (failedCount >= 5 && entryCacheList.isEmpty()) {
                    //fail 5 times. Sleep current thread. 
                        failedCount = 0;
                        Thread.sleep((sleepTime + MIN_SLEEP_TIME) % MAX_SLEEP_TIME);
                    }
                }
                //Insert 1000 rows once
                if (entryCacheList.size() >= 1000) {
                    insertLogList(entryCacheList);
                    entryCacheList.clear();
                }
            } catch (Exception e) {
                logger.warn(e.getMessage());
            }

还有其他好的方法吗?我认为最完美的方式是队列可以通知工作人员我们获取了数据并获取它们。

For some reason we plan to use kestrel queue in our project. We do some demons, the main problem is how to to fetch data from queue with low CPU utilization and effectively. The way we implemented to fetch is if we failed to fetch data from queue more than 5 times, we sleep the thread 100ms to reduce the CPU utilization.

while (running) {
            try {
                LoginLogQueueEntry data = kestrelQueue.fetch();
                if (null != data && data.isLegal()) {
                    entryCacheList.add(data); //add the data to the local caceh
                    resetStatus();
                } else {
                    failedCount++;
                    //if there is no data in the kestrel and the local cache is not empty, insert the data into mysql database
                    if (failedCount == 1 && !entryCacheList.isEmpty()) {
                        resetStatus();
                        insertLogList(entryCacheList); // insert current data into database
                        entryCacheList.clear(); //empty local cache
                    }

                    if (failedCount >= 5 && entryCacheList.isEmpty()) {
                    //fail 5 times. Sleep current thread. 
                        failedCount = 0;
                        Thread.sleep((sleepTime + MIN_SLEEP_TIME) % MAX_SLEEP_TIME);
                    }
                }
                //Insert 1000 rows once
                if (entryCacheList.size() >= 1000) {
                    insertLogList(entryCacheList);
                    entryCacheList.clear();
                }
            } catch (Exception e) {
                logger.warn(e.getMessage());
            }

Is there any other good way to do so? The perfect the way i think is the queue can notice to the worker that we got data and fetch them .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

韶华倾负 2024-11-25 19:46:10

此处的“Memcache 命令”下描述了阻止读取: https://github .com/robey/kestrel/blob/master/docs/guide.md

您可以将选项标志添加到 get 命令中,方法是用斜杠分隔选项标志,以便从“作业”队列中获取项目,等待一秒钟:

get jobs/t=1000

如果一秒钟内队列中没有任何内容显示,您将得到相同的空响应,仅比现在得到的晚一秒钟。 :)

执行此操作时,调整响应超时非常重要。如果您使用超时为 1 秒的阻塞读取,但客户端库的响应超时为 500 毫秒,则库将在阻塞读取完成之前与服务器断开连接。因此,请确保响应超时大于您在读取请求中使用的超时。

Blocking reads are described here, under "Memcache commands": https://github.com/robey/kestrel/blob/master/docs/guide.md

You can add option flags to a get command by separating them with slashes, so to fetch an item from the "jobs" queue, waiting up to one second:

get jobs/t=1000

If nothing shows up on the queue in one second, you'll get the same empty response, just one second later than you're getting it now. :)

It's important to tune your response timeout when you do this. If you use a blocking read with a timeout of one second, but your client library's response timeout is 500 milliseconds, the library will disconnect from the server before the blocking read is finished. So make sure the response timeout is greater than the timeout you're using in the read request.

不必在意 2024-11-25 19:46:10

您需要使用阻塞 get。我无法找到 API 文档,但我发现一篇文章表明这​​在 kestrel 中是可能的。

You need to use a blocking get. I couldn't track down the API docs, but I found an article suggesting that it's possible in kestrel.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文