全局内存计数器是线程安全的并且每x增量刷新到mysql [英] Global in-memory counter that is thread-safe and flushes to mysql every x increments

查看:216
本文介绍了全局内存计数器是线程安全的并且每x增量刷新到mysql的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以创建所有servlet将使用的内存计数器?



此全局计数器将跟踪Web应用程序的浏览量,计数器将特定于当前登录的用户。 1;

在一定的间隔或浏览量计数,我想保存当前计数到mysql row)例如:

  table_pageviews [id,userId,pageview_count,date] 
/ pre>

因此,这个计数器在刷新后将被重置为0.



所有servlet将继承的BaseServlet,我将如何定义此字段? (final,static?)



ConcurrentHashMap是否适合?也许我可以为每个条目的值存储一个AtomicLong。



在刷新期间,我可以使用原子long的getAndSet设置为0,并保存我'get'的值: http://docs.oracle.com/javase/1.5.0/docs/ api / java / util / concurrent / atomic / AtomicLong.html



我必须在刷新期间同步到mysql进程吗?



因此,即使我有10个服务器,每个都有自己的内存计数器,事情仍然会工作,因为他们将最终刷新他们的计数到db,然后我将简单地聚合行,以获得最终的计数。

解决方案

这是可能的;但不建议。使用我的精神超能力我推断,你试图实现一些统计收集工具,你喜欢统计每个用户每时间积累的统计。



你可以使用方法与servlet过滤器和同步方法,它将不时更新数据库
但是你会遇到以下问题:
- 在多个服务器上的应用程序集群
- 管理数据库连接和事务
如果你不需要实时统计,你不会开发这个工具,否则你只需坚持每24小时的日志处理)



这是更好的做的NoSQL数据库像redis ,和一些键的值的原子增量。只需使用userid:startOfIntervalInMisllisecondsSince1970作为键,并增加此值。
- 它是快速
- atomic
- 数据总是安全的
- 不需要共享任何东西,并在负载均衡集群或容器中的多个线程之间进行同步。


Is it possible to create an in-memory counter that all servlets will use?

This global counter will keep track of pageviews for a web application, and the counter will be specific to the currently logged in user. i.e. the collection will have a key for each user.

globalCounterMap[userId].incrementCounter += 1;

At a certain interval or pageview count, I want to save the current count to mysql (insert a new row) e.g.:

table_pageviews [id, userId, pageview_count, date]

So this counter will then get reset to 0 after the flush.

So if I have a BaseServlet that all servlets will inherit from, how would I define this field? (final, static?)

Is the ConcurrentHashMap suitable? Maybe I can store an AtomicLong for the value for each entry.

During the flush, I can use the getAndSet of the atomic long by setting to 0, and saving the value that I 'get': http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicLong.html

Do I have to synchronize during the flush to mysql process? (Say I do this every 1K pageviews)

Update

So even if I have 10 servers, each with their own in-memory counters, things will still work since they will all eventually flush their counts to the db and then I will simply aggregate the rows to get the final counts.

解决方案

This is possible; but not advisable. Using my mental superpowers I deduce that you try to implement some statistics gathering tool, and you like to have statistic accumulated per user per time interwal.

You can use approach with servlet filter and synchronized method, which will update database from time to time But you will run into problems with: - application clustering over several servers - managing database connections and transactions ( you will not develop this tool if you do not need realtime statistics, otherwise you can just stick with log processing every 24 hours)

This is better done with NoSQL database like redis, and atomic increments of value of some key. Just use "userid:startOfIntervalInMisllisecondsSince1970" as key, and increment this value. - it is fast - atomic - data is always safe - no need to share anything and synchronize across load balanced cluster or between multiple threads in your container.

这篇关于全局内存计数器是线程安全的并且每x增量刷新到mysql的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆