首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Java

在本地用内存数据库,除了 hashMap,还有哪些内存数据库方案?

  •  
  •   tctc4869 · 17 天前 · 3110 次点击

    目前主要是在单个服务器上使用,暂不考虑 redis 这种比较复杂面向分布式集群的内存数据库,首先是性能优先。我听说 HashMap,如果用字符串做 key,似乎会有 Hash 值重复的可能?

    在 Spring 容器启动时会读取数据库的一些数据,并会永久地驻留在服务端的内存中。而另一些数据类型会有过期处理等,如果要用 kV 类型的内存数据库的话,有些数据类型,可能会用整型做 key,也可能会用字符串做 key,这两种方式不可避免

    第 1 条附言  ·  17 天前
    有怎么多人推荐 redis,但是我想要的是能在 java 中,直接能通过 new 的方式进行配置的缓存库框架,例如使用静态的 HashMap 作为缓存库,但 HashMap 功能太单一了,我也知道 redis,但在 redis 配置的方式相对于 new 配置方式有点麻烦,已经有人推荐了 guava,caffeine,这两种我稍微查了一下资料,可以直接在 java 中以 new 的方式创建,并进行配置。
    42 回复  |  直到 2019-11-21 08:49:05 +08:00
        1
    phantomzz   17 天前   ♥ 2
        2
    knightdf   17 天前
    为啥 redis 不考虑?明明 redis 就是就是最适合你的,redis 单机集群都可以用
        3
    hyl24   17 天前
    hash 冲突是必然存在的。建议好好学习一下 hashmap 原理。redis 也可以很简单呀单机使用没啥麻烦的。当然也可以选择 ehcache 或者 guava 的缓存 都是 java 进程内的缓存。。。。其次好像没有什么东西是可以永久存在内存中的吧。系统重启都需要从持久化到磁盘的数据恢复到内存的,不然也是内存预热重新加载进去的。
        4
    tusik   17 天前
    h2 也行,redis 单机也能跑得很好啊
        5
    xmh51   17 天前
    hash 重复 不代表不能识别不同的 key 呀。hash map 保证 key 的唯一性
        6
    changdy   17 天前   ♥ 1
    感觉楼主思路有点不清晰
    一方面追求性能 但是另外一方面对 内存 以及 hashmap 的模型并不清楚.
    其实读取数据+序列化反序列化的耗时在一套业务逻辑里面耗时是比较低的

    如果自己实现的话 一定要注意线程安全
        7
    passerbytiny   17 天前   ♥ 2
    你是不是对 数据库 这三个字的量级有误解?不管是 HashMap 还是 Key-Value,最多只能叫做(内存)数据,而不是(内存)数据库。
    Oracle (公司)有一款内存数据库,其他大型数据库厂商一般也都会有内存数据库,它们在操作方式上属于仅提供有限功能的标准关系型数据库,掏钱就能用。除此之外,Redis 是最入门的 NoSQL 型内存数据库了,入门到功能都不完全,需要搭配 Spring Data Redis 配套使用。
        8
    woshiaha   17 天前
    我听说 HashMap,如果用字符串做 key,似乎会有 Hash 值重复的可能?

    ------如果你 HashMap 都没整明白的话,还是直接用 redis 算了。。。。
        10
    nnnToTnnn   17 天前
    ```
    static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    ```

    如果这还存在 hash 冲突,建议你去买张彩票,说真的。
        11
    wysnylc   17 天前
    apache 有 lru
    但是建议使用 redis
        12
    zunceng   17 天前
    blotdb rocksdb 这种? 或者直接 sqlite
        13
    crossoverJie   17 天前
    本地缓存配合 Redis 使用也很常见,推荐使用 Google 的 Guava 库,各种缓存特性都有。
        14
    tctc4869   17 天前
    @passerbytiny 内存数据库不就是缓存库的一种称呼吗?
    你就这么纠结“数据库”这个三个字的文字概念吗,“不管是 HashMap 还是 Key-Value,最多只能叫做(内存)数据,而不是(内存)数据库。”,HashMap 在你眼里只能叫数据,key-value 只能叫数据?那 leveldb 这种持久化的 kv 数据库在你眼里就不是数据库了,叫数据文件是吧,你的意思是瞧不起持久化的 kv 数据库吗,那 sqlite 这种也不是数据库,是数据文件对吧。文字游戏好玩吗。

    redis 数据库有缓存库功能,也有持久化功能,那它就不是内存数据库?或者不是磁盘数据库了?你纠结文字概念干嘛,分的清楚就可以。我是来问怎么选缓存库方案的,不是来玩文字概念游戏的。内存数据库的合适称呼是叫缓存库,谁不知道?与之不同的是磁盘数据库,网上叫来叫去都说成约定俗成了,我用"内存数据库"这个词不行吗。
        15
    newtype0092   17 天前
    要达到你的要求我一时还真想不到比 redis 更简单更高效的东西了。。。
    打开 redis 官网第一段话的介绍,只有最后一句提到了通过集群方式可以提供一些高可用特性,“面向分布式集群”是你自己给自己加戏~
        16
    haoz1w0w   17 天前   ♥ 1
    @nnnToTnnn #10 肯定会存在 hash 冲突的 否则 hashmap 为什么要挂个链表呢?
        17
    yuikns   17 天前   ♥ 1
    我寻思楼主就是想要一个基于 Java 的 embedded cache solution

    guava 有个 CacheBuilder 似乎就是你想要的? https://github.com/google//wiki/CachesExplained
        18
    yuikns   17 天前
        19
    passerbytiny   17 天前
    @tctc4869 #13 拜拜
        20
    tctc4869   17 天前
    @newtype0092 我目前其实并不想要具备的持久化功能的缓存库,而且不是 xml 中配置,是直接在 java 通过静态字段的 new 的方式,直接以 new 或创建为配置的那种,然后用封装一下,例如用静态的 hashMap 作为一个缓存库,但静态的 hashmap 功能有点少。redis 配置有点麻烦,而且关乎于端口和 ip,楼上有人推荐 guava,caffeine 这两种的话比较符合,可以直接在 java 中通过静态字段的进行 new 创建的方式进行配置。毕竟不同的缓存功能要对应不用的数据类型,简单可以直接有 hashmap,有些还得具备的简单的关系数据功能。
        21
    boyhailong   17 天前
    单机使用的内存数据库还是本地缓存?
    单机 redis 的确是最优解,具体的过期需求可以设置,占用总内存也可以设置,单机还是集群可配置,是否存储落地也可配置,搜“AOF 和 RDB 禁止持久化”。你能想到的关于内存数据库的使用场景,redis 开发者都想到了,蟹蟹
        22
    skypyb   17 天前 via Android
    redis 还配置麻烦?你在这发帖的几十分钟里够配置十来个集成 redis 的 spring 项目了。
        23
    sunjiayao   17 天前
    楼上 guava 正解
        24
    fengpan567   17 天前
    ehcache
        25
    kayv   17 天前
    ehcache 或者 google guava 都可以。如果缓存不需要失效,直接上 Map
        27
    nnnToTnnn   17 天前
    @haoz1w0w 是存在理论上的 hash 碰撞,这个 hash 碰撞还不如 md5 的 hash 碰撞明显,如果真的存在 hash 碰撞了,你的机器内存也并不足够支撑你的数据存储。 如果你觉得这样不保险。还可以继续加盐值,但是我觉得没有必要了。

    你可以参考下 md5 的 hash 碰撞需要多大的数据量
        28
    nnnToTnnn   17 天前
    准确的说,这个 hash 碰撞,不如 md5 16 的明显,在 md5 32 中加大的盐值,减少了碰撞几率。

    理论 hashmap 的 key 字节大小相差特别大,才能可能遇到 hash 碰撞。

    我实在是不明白,什么样的情况下你的 key 会大到产生 hash 冲突? 这让我很懵啊。
        29
    Bromine0x23   17 天前
    用 Redis 和 new 对象又不矛盾,spring-data-redis 就有对 redis 包装的容器类实现
        30
    MyShoW   17 天前
    redis+redisson 也可以考虑一下,直接操作对象,不用关心 redis 的存取
        31
    haosamax   17 天前
    冲突的概率也太小了吧,就算冲突了又有什么关系呢
        32
    sagaxu   16 天前 via Android   ♥ 1
    连 map 是啥都不知道的人,也来看不起内存 map 之王了?
        33
    CoderGeek   16 天前
    guava Caffeine
        34
    ErrorMan   16 天前
    内存型数据库 h2,可以嵌入 java
        35
    hantsy   16 天前
    @tctc4869 Hazelcast , infinispan
        36
    hzgit   16 天前
    比较主流的就是 guava cache 和 encache 了 ( ps. HashMap 并不是内存数据库哦)
        37
    Raymon111111   16 天前
    ?

    如果你是为了解决 hash 冲突

    那应该是没有现成方案的
        38
    zhady009   16 天前 via iPhone
    @MyShoW 这个最近在用 真的香
        39
    areless   16 天前 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   16 天前 via Android
    sql 快了,那么构架就回归原始。现在像巫师一样的构架师~~~全文本外部索引用 es,kv 用 redis,存储用 mysql 或 pg 或等等等。http 请求负载,构架的重要胜于传统,胜于标准化。这是不合理的。用 sql like 快于 es,sql 内存表快于 redis,apache 常驻模式快于 nginx 才是标准化。
        41
    wangyzj   16 天前
    redis 已经很简单了把
    而且你能保证你自己做 hashmap 会比 redis 性能好么?
    你还得考虑种种问题情况
        42
    johnnyho   16 天前 via iPhone   ♥ 1
    楼主感觉就是懂得比较少,又要嘴硬那种存在…虚心接受指导不好吗
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2260 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 27ms · UTC 10:25 · PVG 18:25 · LAX 02:25 · JFK 05:25
    ♥ Do have faith in what you're doing.