目前主要是在单个服务器上使用,暂不考虑 redis 这种比较复杂面向分布式集群的内存数据库,首先是性能优先。我听说 HashMap,如果用字符串做 key,似乎会有 Hash 值重复的可能?
在 Spring 容器启动时会读取数据库的一些数据,并会永久地驻留在服务端的内存中。而另一些数据类型会有过期处理等,如果要用 kV 类型的内存数据库的话,有些数据类型,可能会用整型做 key,可能会用字符串做 key,这两种方式不可避免
1 0NF09LJPS51k57uH 2019-11-20 09:32:32 +08:00 ![]() |
![]() | 2 knightdf 2019-11-20 09:42:19 +08:00 为啥 redis 不考虑?明明 redis 就是就是最适合你的,redis 单机集群都可以用 |
![]() | 3 hyl24 2019-11-20 09:43:17 +08:00 hash 冲突是必然存在的。建议好好学习一下 hashmap 原理。redis 也可以很简单呀单机使用没啥麻烦的。当然也可以选择 ehcache 或者 guava 的缓存 都是 java 进程内的缓存。。。。其次好像没有什么东西是可以永久存在内存中的吧。系统重启都需要从持久化到磁盘的数据恢复到内存的,不然也是内存预热重新加载进去的。 |
![]() | 4 tusik 2019-11-20 09:43:57 +08:00 h2 也行,redis 单机也能跑得很好啊 |
![]() | 5 xmh51 2019-11-20 09:45:06 +08:00 hash 重复 不代表不能识别不同的 key 呀。hash map 保证 key 的唯一性 |
![]() | 6 changdy 2019-11-20 09:49:17 +08:00 ![]() 感觉楼主思路有点不清晰 一方面追求性能 但是另外一方面对 内存 以及 hashmap 的模型并不清楚. 其实读取数据+序列化反序列化的耗时在一套业务逻辑里面耗时是比较低的 如果自己实现的话 一定要注意线程安全 |
7 passerbytiny 2019-11-20 09:55:55 +08:00 ![]() 你是不是对 数据库 这三个字的量级有误解?不管是 HashMap 还是 Key-Value,最多只能叫做(内存)数据,而不是(内存)数据库。 Oracle (公司)有一款内存数据库,其他大型数据库厂商一般也都会有内存数据库,它们在操作方式上属于仅提供有限功能的标准关系型数据库,掏钱就能用。除此之外,Redis 是最入门的 NoSQL 型内存数据库了,入门到功能都不完全,需要搭配 Spring Data Redis 配套使用。 |
8 woshiaha 2019-11-20 09:55:57 +08:00 我听说 HashMap,如果用字符串做 key,似乎会有 Hash 值重复的可能? ------如果你 HashMap 都没整明白的话,还是直接用 redis 算了。。。。 |
![]() | 9 min 2019-11-20 09:58:12 +08:00 |
10 nnnToTnnn 2019-11-20 09:59:17 +08:00 ``` static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } ``` 如果这还存在 hash 冲突,建议你去买张彩票,说真的。 |
![]() | 11 wysnylc 2019-11-20 10:00:27 +08:00 apache 有 lru 但是建议使用 redis |
![]() | 12 zunceng 2019-11-20 10:19:26 +08:00 blotdb rocksdb 这种? 或者直接 sqlite |
![]() | 13 crossoverJie 2019-11-20 10:19:38 +08:00 本地缓存配合 Redis 使用也很常见,推荐使用 Google 的 Guava 库,各种缓存特性都有。 |
![]() | 14 tctc4869 OP @passerbytiny 内存数据库不就是缓存库的一种称呼吗? 你就这么纠结“数据库”这个三个字的文字概念吗,“不管是 HashMap 还是 Key-Value,最多只能叫做(内存)数据,而不是(内存)数据库。”,HashMap 在你眼里只能叫数据,key-value 只能叫数据?那 leveldb 这种持久化的 kv 数据库在你眼里就不是数据库了,叫数据文件是吧,你的意思是瞧不起持久化的 kv 数据库吗,那 sqlite 这种也不是数据库,是数据文件对吧。文字游戏好玩吗。 redis 数据库有缓存库功能,也有持久化功能,那它就不是内存数据库?或者不是磁盘数据库了?你纠结文字概念干嘛,分的清楚就可以。我是来问怎么选缓存库方案的,不是来玩文字概念游戏的。内存数据库的合适称呼是叫缓存库,谁不知道?与之不同的是磁盘数据库,网上叫来叫去都说成约定俗成了,我用"内存数据库"这个词不行吗。 |
15 newtype0092 2019-11-20 10:30:32 +08:00 要达到你的要求我一时还真想不到比 redis 更简单更高效的东西了。。。 打开 redis 官网第一段话的介绍,只有最后一句提到了通过集群方式可以提供一些高可用特性,“面向分布式集群”是你自己给自己加戏~ |
![]() | 17 yuikns 2019-11-20 10:38:59 +08:00 ![]() 我寻思楼主就是想要一个基于 Java 的 embedded cache solution guava 有个 CacheBuilder 似乎就是你想要的? https://github.com/google//wiki/CachesExplained |
![]() | 18 yuikns 2019-11-20 10:44:33 +08:00 @yuikns 不好意思 fix 下 : https://github.com/google/guava/wiki/CachesExplained |
![]() | 19 passerbytiny 2019-11-20 10:46:28 +08:00 @tctc4869 #13 拜拜 |
![]() | 20 tctc4869 OP @newtype0092 我目前其实并不想要具备的持久化功能的缓存库,而且不是 xml 中配置,是直接在 java 通过静态字段的 new 的方式,直接以 new 或创建为配置的那种,然后用封装一下,例如用静态的 hashMap 作为一个缓存库,但静态的 hashmap 功能有点少。redis 配置有点麻烦,而且关乎于端口和 ip,楼上有人推荐 guava,caffeine 这两种的话比较符合,可以直接在 java 中通过静态字段的进行 new 创建的方式进行配置。毕竟不同的缓存功能要对应不用的数据类型,简单可以直接有 hashmap,有些还得具备的简单的关系数据功能。 |
![]() | 21 boyhailong 2019-11-20 11:08:26 +08:00 单机使用的内存数据库还是本地缓存? 单机 redis 的确是最优解,具体的过期需求可以设置,占用总内存也可以设置,单机还是集群可配置,是否存储落地也可配置,搜“AOF 和 RDB 禁止持久化”。你能想到的关于内存数据库的使用场景,redis 开发者都想到了,蟹蟹 |
![]() | 22 skypyb 2019-11-20 11:52:59 +08:00 via Android redis 还配置麻烦?你在这发帖的几十分钟里够配置十来个集成 redis 的 spring 项目了。 |
23 luman 2019-11-20 12:12:40 +08:00 楼上 guava 正解 |
24 fengpan567 2019-11-20 12:26:29 +08:00 ehcache |
![]() | 25 kayv 2019-11-20 12:39:06 +08:00 ehcache 或者 google guava 都可以。如果缓存不需要失效,直接上 Map |
![]() | 26 zhuangzhuang1988 2019-11-20 13:17:38 +08:00 |
27 nnnToTnnn 2019-11-20 13:28:10 +08:00 @haoz1w0w 是存在理论上的 hash 碰撞,这个 hash 碰撞还不如 md5 的 hash 碰撞明显,如果真的存在 hash 碰撞了,你的机器内存也并不足够支撑你的数据存储。 如果你觉得这样不保险。还可以继续加盐值,但是我觉得没有必要了。 你可以参考下 md5 的 hash 碰撞需要多大的数据量 |
28 nnnToTnnn 2019-11-20 13:38:42 +08:00 准确的说,这个 hash 碰撞,不如 md5 16 的明显,在 md5 32 中加大的盐值,减少了碰撞几率。 理论 hashmap 的 key 字节大小相差特别大,才能可能遇到 hash 碰撞。 我实在是不明白,什么样的情况下你的 key 会大到产生 hash 冲突? 这让我很懵啊。 |
![]() | 29 Bromine0x23 2019-11-20 13:50:00 +08:00 用 Redis 和 new 对象又不矛盾,spring-data-redis 就有对 redis 包装的容器类实现 |
30 MyShoW 2019-11-20 14:08:48 +08:00 redis+redisson 也可以考虑一下,直接操作对象,不用关心 redis 的存取 |
![]() | 31 haosamax 2019-11-20 18:01:00 +08:00 冲突的概率也太小了吧,就算冲突了又有什么关系呢 |
![]() | 32 sagaxu 2019-11-20 18:32:02 +08:00 via Android ![]() 连 map 是啥都不知道的人,也来看不起内存 map 之王了? |
![]() | 33 CoderGeek 2019-11-20 20:38:56 +08:00 guava Caffeine |
34 ErrorMan 2019-11-20 20:43:50 +08:00 内存型数据库 h2,可以嵌入 java |
36 hzgit 2019-11-20 21:21:43 +08:00 比较主流的就是 guava cache 和 encache 了 ( ps. HashMap 并不是内存数据库哦) |
37 Raymon111111 2019-11-20 21:28:36 +08:00 ? 如果你是为了解决 hash 冲突 那应该是没有现成方案的 |
![]() | 39 areless 2019-11-20 22:15:56 +08:00 via Android key md5 值建文件夹,把 val 写 key 的 md5 文件夹内的文件内,假若是 obj 序列化,json 分多文件,存到 linux 的 shm 里,这就是最简单的内存 kv 数据库了,以前称之为文本数据库。而且速度不会太慢。mysql 的慢是因为 sql~~~假设 sql 查询通过 gpu 去操作显存就没有像 cpu 去操作机械硬盘这种低速记录体的瓶颈。所以未来会回归 sql,淘汰掉 nosql 做前置缓存的。所以别研究怎么搞一个速度比舒马赫还快的 kv 或者 hashmap,研究一下怎么让正规的 sql 比拟 nosql 吧 |
![]() | 40 areless 2019-11-20 22:26:29 +08:00 via Android sql 快了,那么构架就回归原始。现在像巫师一样的构架师~~~全文本外部索引用 es,kv 用 redis,存储用 mysql 或 pg 或等等等。http 请求负载,构架的重要胜于传统,胜于标准化。这是不合理的。用 sql like 快于 es,sql 内存表快于 redis,apache 常驻模式快于 nginx 才是标准化。 |
![]() | 41 wangyzj 2019-11-21 00:36:11 +08:00 redis 已经很简单了把 而且你能保证你自己做 hashmap 会比 redis 性能好么? 你还得考虑种种问题情况 |
42 johnnyho 2019-11-21 08:49:05 +08:00 via iPhone ![]() 楼主感觉就是懂得比较少,又要嘴硬那种存在…虚心接受指导不好吗 |
43 betajun 2019-12-23 16:43:18 +08:00 现在线上使用的 guava 做 jvm 内缓存来兜底,没有出现过什么问题。但是你需要预估一下你的数据量,数据量太大造成频繁 gc。 |
![]() | 44 Jacky23333 2020-01-25 17:07:15 +08:00 via Android 楼主不是科班出身吗,没学过数据结构,不管你用什么类型做 key 也肯定会出现 Hash 冲突的呀 |