回顾总结四、数据存储与共享

一、方法

数据共享的方法如下:

  • 参数传递
  • ETS
  • DETS
  • DICT(进程字典)

二、作用域

  • 参数传递:在函数间共享数据
  • ETS:同一节点多进程间数据共享,保存在RAM中,非持久化保存
  • DETS:同一节点多进程间数据共享,保存在DISK中,持久化保存
  • DICT(进程字典):保存在单一进程独立内存中,只在进程中可读写

三、原理

  • 参数传递
    Erlang的参数传递是值传递并非引用传递,所以传递时会复制一份副本
    另外是原子atom的时候,erlang 的垃圾回收机制是不回收的(因为原子类型不参与垃圾回收)
    效率:当数据越大时,参数传递效率越低

  • ETS
    ets一共有4种类型的表:set、ordered_set、bag、duplicate_bag,其中(set、bag、duplicate_bag)是由哈希结构保存,时间复杂度为O(1)
    而ordered_set是由平衡二叉树结构保存,时间复杂度为O(logN)

    4种表的比较:
    set与ordered_set比是set效率更高、bag和duplicate_bag比是duplicate_bag效率高,
    因为bag要去比较是否有Value重复

    注意ETS是有读写锁的!而且因为数据不在进程中,所以查询时会产生一份副本

  • DICT(进程字典)
    进程字典是动态哈希表实现的字典,因为数据内存位置与数据有对应的函数关系,所以查找起来效率很快,从而增加和删除都很快(进程字典的操作效率基于查询的效率)
    另外,进程字典是无锁操作的,数据在进程中,不会产生副本

  • DETS
    DETS和ETS是相似的,DETS只有3种表,没有ordered_set、它的每个函数都会操作磁盘IO,它将数据组织为线性哈希表,效率比ETS慢

四、各自的特性(优缺点)

  • ETS
    1、生命周期方面,当创建表的进程挂了,数据有可能丢失(除非指派给其他进程了)
    2、数据方面,ets表内的数据不参与垃圾回收,只有当主动删除表或者创建表的进程退出了才会清空
    3、锁方面,进程字典为无锁操作
    4、操作方面,数据不在进程中,所以查询时会产生一份复制的副本、发生一次拷贝内存
    5、储存大小方面,能存储的数据量取决于内存的大小

  • DETS
    1、储存大小方面,最大文件大小限制为2G
    2、操作方面,每个函数都对磁盘产生操作
    其余都和ETS一致

  • DICT
    1、数据方面,进程字典数据在进程中,查询没有多余的复制操作,因此效率也最快
    2、锁方面,进程字典是无锁的
    3、生命周期方面,和所在进程的生命周期相关

五、应用场景

1、在某个进程中频繁访问大块的数据(单进程)
进程字典>ets>mnesia(ets+dets)

2、多个进程共享某个数据(同一节点跨进程)
有两种可用方式:a.消息传递 b.ets
使用消息传递如果是大块数据的话成本太大,消息传递的流程如下:
1) 计算消息的大小,并在接收进程的内存空间中给消息分配内存;
2) 将消息的内容拷贝到接收进程的堆内存中;
3) 最后将消息的地址添加到接收进程的消息队列。
虽然ets也符合也很方便,但是如果是过多进程(成千上万)去访问同一个表会产生阻塞,因为ets有读写锁,他保证每一个操作都是原子性和隔离性的,就好像所有隔离的操作一个接一个严格按照顺序执行。

3、多个节点内的进程共享数据(跨节点)
这个时候我认为mnesia是最好的选择,每个联通的节点上都会启动一套mnesia进程,去管理每个节点上的mnesia并会和其他节点交换数据,保证大家的数据都是一致的



 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值