目前主要是在单个服务器上使用,暂不考虑 redis 这种比较复杂面向分布式集群的内存数据库,首先是性能优先。我听说 HashMap,如果用字符串做 key,似乎会有 Hash 值重复的可能?
在 Spring 容器启动时会读取数据库的一些数据,并会永久地驻留在服务端的内存中。而另一些数据类型会有过期处理等,如果要用 kV 类型的内存数据库的话,有些数据类型,可能会用整型做 key,也可能会用字符串做 key,这两种方式不可避免
1
phantomzz 2019-11-20 09:32:32 +08:00 2
|
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 1
感觉楼主思路有点不清晰
一方面追求性能 但是另外一方面对 内存 以及 hashmap 的模型并不清楚. 其实读取数据+序列化反序列化的耗时在一套业务逻辑里面耗时是比较低的 如果自己实现的话 一定要注意线程安全 |
7
passerbytiny 2019-11-20 09:55:55 +08:00 2
你是不是对 数据库 这三个字的量级有误解?不管是 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 1
我寻思楼主就是想要一个基于 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
sunjiayao 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 1
连 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 1
楼主感觉就是懂得比较少,又要嘴硬那种存在…虚心接受指导不好吗
|
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 冲突的呀
|