1. 特性
curl命令上传 浏览器上传 断点续传(tus) 秒传 http下载 断点下载 小文件自动合并(减小incode占用)配置自动生成 google认证码 自定义认证 自监控告警 跨域访问 一键迁移 并行体验 类fastdfs多机自动同步 集群文件信息查看 高性能(使用leveldb作为kv库) 高可靠(设计极其简单,使用成熟组件) 无中心设计(所有节点都可以同时读写) docker部署
2. 优点
无依赖(单一文件) 自动同步 失败自动修复按天分目录自动去重目录自定义 保留原文件名 自动生成唯一文件名 token下载(token=md5(file_md5+timestamp))单一角色(无Tracker Server,Storage Server,Client)集群监控邮件告警节点对等 节点同时读写
3. Tus
轻量级断点续传协议,服务端是用go编写,客户端也支持JavaScript、Andorid、Java、IOS,客户端在创建链接的时候上传必要的参数,服务端根据客户端传的参数寻找对应的文件,并返回上次上传的位置给客户端。客户端根据服务的返回的偏移量再进行上传。
Tus使用了文件名和大小作为文件的唯一性。如果文件名相同,文件大小也相同,那么服务端就认为是同一个文件。
4. LevelDB
LevelDB是Google的Jeff Dean和Sanjay Ghemawat设计开发的key-value存储引擎。LevelDB底层存储利用了LSM tree的思想,RocksDB是Facebook基于LevelDB开发的存储引擎,针对LevelDB做了很多优化,但是大部分模块的实现机制是一样的。
LevelDB是一个持久化存储的KV系统,和Redis这种内存型的KV系统不同,LevelDB不会像Redis一样狂吃内存,而是将大部分数据存储到磁盘上。LevleDB在存储数据时,是根据记录的key值有序存储的,就是说相邻的key值在存储文件中是依次顺序存储的,而应用可以自定义key大小比较函数,LevleDB会按照用户定义的比较函数依序存储这些记录。
LevelDB的操作接口简单,满足基本增删改查操作。另外,LevelDB支持数据快照(snapshot)功能,使得读取操作不受写操作影响,可以在读操作过程中始终看到一致的数据。LevelDB还支持数据压缩等操作,这对于减小存储空间以及增快IO效率都有直接的帮助。
4.1. Memtable
DB数据在内存中的存储方式,写操作会先写入memtable,memtable有最大限制(write_buffer_size)。LevelDB/RocksDB的memtable的默认实现是skiplist。当memtable的size达到阈值,会变成只读的memtable(immutable memtable)。后台compaction线程负责把immutable memtable dump成sstable文件。RocksDB增加了column family的概念,不同的column family不共享memtable,其他memtable机制与LevelDB一样。
4.2. sstable
DB数据持久化文件,内部key是有序的,文件内部前面是数据,后面是索引元数据。sstable文件之间逻辑上是分层的,LevelDB最大支持7层。
4.3. SequenceNumber
LevelDB中每次写操作(put/delete)都有一个版本,由sequence number来标识,整个DB有一个全局值保存当前使用的SequenceNumber,key的排序以及snapshot都要依赖它。
4.4. Version
将每次compact后的最新数据状态定义为一个version,也就是当前DB的元信息以及每层level的sstable的集合。跟version有关的一个数据结构是VersionEdit,记录了一次version的变化,包括删除了哪些sstable,新增了哪些sstable。old version + versionedit= new version。整个DB存在的所有version被VersionSet数据结构保存,这个数据结构包含:全局sequencenumber、filenumber、tablecache、每个level中下一次compact要选取的start_key。
4.5. FileNumber
DB创建文件时将FileNumber加上特定的后缀作为文件名,FileNumber在内部是一个uint64_t类型,并且全局递增。不同类型的文件的拓展名不同,例如sstable文件是.sst,wal日志文件是.log。LevelDB文件类型:
enum FileType {kLogFile,kDBLockFile,kTableFile,kDescriptorFile,kCurrentFile,kTempFile,kInfoLogFile // Either the current one, or an old one};
4.6. Key
LevelDB对于用户输入的key做了不同的处理,user_key表示用户输入的key,internal_key是DB内部使用的key,在uers_key的基础上添加了sequencenumber和valuetype。
4.7. compact
DB有一个后台线程负责将memtable持久化成sstable,以及均衡整个DB各个level层的sstable。compact分为minor compaction和major compaction。memtable持久化成sstable称为minor compaction,level(n)和level(n+1)之间某些sstable的merge称为major compaction。
LevelDB的架构图,黄线上面是内存组件,黄线下面是磁盘组件。内存组件包括memtable、immutable memtable、log,磁盘组件包括:CURRENT文件、MANIFEST文件、.log文件、LOG文件、LOCK锁文件。
操作接口Put是写数据的接口,数据先写入log文件,然后写入memtable,如果memtable大小超过了设定的阈值,则memtable转成immutable memtable,immutable memtable只能读不能写。Immutable memtable会compact到磁盘上形成sstable文件。操作接口Get是读数据的接口。
读数据的顺序是:1.memtable 2.immutable memtable 3.sst file。
sstable文件是用户数据在磁盘上持久化存储的文件,逻辑上按层存储,内部按key排序,除了L0层外,其他层sstabel文件的key之间没有重叠。LevelDB支持多版本,MANIFEST文件记录了版本变化的信息,随着sstable文件增多,MANIFEST文件也是会增多的,所以CURRENT文件指向当前的MANIFEST文件。除了immutable memtable会compact成sstable文件,磁盘上相邻层之间也会发生compaction操作。
4.8. WAL
Write-ahead Log 现在关系型数据库几乎都提供了WAL机制,WAL机制即先写日志数据,后写用户数据,这样保证了用户数据持久化。在数据库意外宕机时,可以利用WAL恢复到宕机前的状态。LevelDB的日志格式:
Log相关的代码:
db/log_format.hdb/log_reader.hdb/http://log_reader.ccdb/log_writer.hdb/http://log_writer.cc
value有可能太大,因此无法存放在一个block,会跨block存储,因此leveldb提供了RecordType枚举类型。
payload的格式:
LevelDB的删除操作是标记删除,并没有真正删除原来的数据,真正的删除操作通过compaction删除,为了区分写入的数据类型,LevelDB定义了ValueType枚举类型:
enum ValueType {
kTypeDeletion = 0x0,
kTypeValue = 0x1
}
