演示IPFS的一个完整的流程以及针对部分概念的详解

整体的流程

1,创建ipfs节点

  • 通过ipfs init在本地计算机建立一个IPFS节点
  • 本文有些命令已经执行过了,就没有重新初始化。部分图片拷贝自先前文档,具体信息应以实物为准
$ ipfs init
initializing IPFS node at /Users/CHY/.ipfs
generating 2048-bit RSA keypair...done
peer identity: QmdKXkeEWcuRw9oqBwopKUa8CgK1iBktPGYaMoJ4UNt1MP
to get started, enter:ipfs cat /ipfs/QmVLDAhCY3X9P2uRudKAryuQFPM5zqA3Yij1dY8FpGbL7T/readme$ cd ~/.ipfs
$ ls
blocks		datastore	version config		keystore
$ open ./
  • 执行ipfs init初始化节点之后,会生成一个.ipfs的文件夹,用于存储相关的信息,比如节点ID、环境配置信息、数据存储等
  • 如果使用的是MAC电脑,使用shift+command+. 可以查看隐藏文件

  • 通过ipfs id查看创建的节点id的信息

2,启动节点服务器 

  • 使用命令ipfs daemon启动节点服务器
  • 一旦启动当前界面会处于监听状态,需要新建标签页

3,简单验证

  •  使用如下命令,进行简单测试

ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme

  • 浏览器输入下面的网址:http://localhost:5001/webui会看到一个漂亮的UI界面

 相关问题详解

ipfs的存储位置

  • IPFS的数据存储,个人用户的数据存储在自己个人的硬盘上,也就是本地硬盘存储。存储后,会在IPFS网络广播,“我存储哈希为Qm...的数据了”,因为哈希的唯一性,如果数据的分割方法一定,那么同样的数据在网络存储中只会有一份,也就是只在本地节点存储。当有用户检索该数据时,检索数据的hash值就是key,节点会首先在DHT表(key/value存储)中查询有无该key,如果没有,到与key异或距离最近的K桶里查找,如果该K桶中的某个节点有key对应的value则返回,否则返回它认为存有value值的最可能节点,以此递归,最终找到key对应的value。然后请求节点与value(也就是节点ID)建立连接,并请求数据,同时将该key/value键值对存储到自己的DHT表中。请求节点将接收到的数据存储到ipfs缓存中,数据检索成功。该请求节点在缓存数据有效期内,同样可以为ipfs网络,提供该数据,作为原始数据的备份。

ipfs的冗余备份措施

  • IPFS采用了Erasure coding的冗余备份措施,集群中有n份原始数据和m份校验数据,即共有n+m份备份数据。

修改节点默认存储空间

  • ipfs节点默认存储空间为10个G

方式一:可打开终端执行下面的命令

export EDITOR=/usr/bin/vim
ipfs config edit
  • 找到下图使用红色的框标定的内容,修改自己想要的大小
  • PS:输入i可以开始编辑,编译完毕后按esc键,再输入:,再次输入wq保存并且退出 

方式二 采用web界面进行修改

  • 修改对应的信息,然后点击保存

ipfs的节点掉线,对于整个组织的影响

  • IPFS的容错机制会保证数据被复制了足够数量并存放在不同的地区,即使某一个地方的数据由于不可抗力的因素被完全销毁,通过其他地区的备份也可以实现完整恢复数据,极大的保证了存储在IPFS上的数据的安全性
  • 采用MerkleDAG,因为它具有以下特点:1.内容可寻址:所有内容都是被多重hash校验和来唯一识别的,包括links。2.无法篡改:所有的内容都用它的校验和来验证。如果数据被篡改或损坏,IPFS会检测到。3.重复数据删除:重复内容并只存储一次。
    在IPFS网络中,数据的存储可能是有重复的。重复的数量与用户上传的时候采用的IPFS进行分块的方法有关。
  • 之前提到过数据在IPFS存储是以块的形式存储的。在ipfs提供的数据分割方式有很多种。在ipfs源码种core/commands/add.go代码中描述了切割的方法:
  1. 默认模式,块的大小是256kb,也就是256 * 1024 bytes,对应的size=262144。命令不需要加参数,即ipfs add 文件。
  2. 指定块大小模式。命令是ipfs add --chunker=size-1000。其中后边的1000可以是任意小于262144的数。
  3. rabin可变块大小切割模式。命令是ipfs add --chunker=rabin-[min]-[avg]-[max] 文件。其中min,avg,max的值分别值最小块大小,平均块大小,最大块大小的意思,值在小于262144自行设定。
     
The chunker option, '-s', specifies the chunking strategy that dictates
how to break files into blocks. Blocks with same content can
be deduplicated. The default is a fixed block size of
256 * 1024 bytes, 'size-262144'. Alternatively, you can use the
rabin chunker for content defined chunking by specifying
rabin-[min]-[avg]-[max] (where min/avg/max refer to the resulting
chunk sizes). Using other chunking strategies will produce
different hashes for the same file.> ipfs add ipfs-logo.svg> ipfs add --chunker=size-2048 ipfs-logo.svg> ipfs add --chunker=rabin-512-1024-2048 ipfs-logo.svg
  • 同一个文件存储在ipfs中,因为存储是选用的文件切割方法不同,返回的hash值却不一样。所以说IPFS的块存储没有重复的,而IPFS块文件拼凑的数据可能有重复的。也就是说同一个文件可以根据不同的文件切割方法在IPFS网络中重复的存储多次
  • 备份是如何实现的呢?假如一部非常火的电影,大家都习惯性的将该电影存储到自己的电脑E盘或其它硬盘存储中,全世界如果有1亿的人存储了这个电影,这不是对存储的极大浪费吗?在ipfs网络中,该电影只被存储在一个节点中,当有用户需要读取的时候,会产生新的备份。就是谁使用数据,这个数据就会复制到谁那里。当一个节点加入IPFS网络时,这个节点会提供一部分硬盘空间(缺省为10G,可以配置)给整个网络使用。那么通常情况下,在存储文件的时候,您自己提供的这部分硬盘空间总是最快的,因为不需要跨网。当存储完毕后,网络上任意节点都可以访问这个文件。当另一个节点访问的时候,那个节点往往会复制一份您的数据到他的缓存空间。这样整个网络中就有两份拷贝了。试想,当有很多人对这个文件感兴趣,那么网络中的拷贝数会越来越多。
  • 需要提出的是:拷贝一般都是缓存,也就是说是临时存储的。时间一长就被自动删除掉了。这种临时缓存非常好地解决了分布式数据分发的问题,比如说一个社会热点往往呈现出预热期、火热期和退潮期等阶段,利用IPFS,数据的分布和拷贝数与这些时期是完全匹配的。访问的人越多,拷贝数就越多,但热度下来了,拷贝数就会降下来,从而自然地实现空间利用率和存取效率的平衡。如果想让这个文件永久存储,那么必须将其设为固定的样式,即存储在硬盘中。

ipfs的使用

上传txt文件

 上传其他格式的文件

  • pdf
  • docx
  • jpg
  • mp4
  • mp3

注意事项

  1. 对于下载的文件需要进行格式的准换,否则不可用。这个转化的方式可以手工进行转化,也可以使用命令的方式。
  2. 也可以指定下载的文件名称,加上-o 文件名,也可以加上-a : 压缩成.tar格式,-C :压缩成.gz格

pdf 

ipfs get QmZJBKrLFPvn8zEatZsxSJTtJkCFm4YeMwChDLRPPPerZ6 -o 1.pdf

  • 使用命令open hh.pdf 打开pdf文件,此处open的用法是Linux自带功能,和ipfs无关

docx

mp3 

 jpg

mp4

上传整个文件夹

  • 此处上传的整个文件夹里面的文件和先前测试使用的是相同的文件,所以他们的哈希值是一致的,这个就是ipfs要求的避免相同的文件被用户上传多次。

查看上传的文件中包含的子文件

查看被引用的hash

  • 被引用的hash概念:一般指文件夹下面有多少个文件,这个文件夹的名称就被引用多少次,hash就是应用该文件名的文件hash

如果上传的是一个文件夹,那么将文件夹拉回到本地,里面的文件是正常的存储格式,无需进行格式转化 

 进入web可视化界面,将哈希序列输入到搜索框,进行文件的查询,如果文件不支持预览,需要点击downloading进行下载查看

发现的问题

  •  使用root用户和普通用户,使用ipfs id查看自己的节点信息,还不一样。

 而且,这两个节点之间还不能互相交换文件,不隶属于同一个集群。

参考链接

  • 使用ipfs完成一个图片上传的案例 
  • IPFS:分布式文件存储
  • IPFS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ 算法的时间复杂度

一般ACM或者笔试题的时间限制是1秒或2秒。 在这种情況下&#xff0c;C代码中的操作次数控制在 10^7为最佳。 下面给出在不同数据范国下&#xff0c;代码的时间复杂度和算法该如何选择&#xff1a; 1.n≤ 30,指数级别&#xff0c;dis剪枝&#xff0c;状态压缩dp 2.n < 100 &g…

简单工厂模式实现计算器

#include <iostream> #include <vector> #include <string> #include <iostream> #include <map> using namespace std; #define __THROW_ZERO do {cerr << "The dividend is 0" << endl; exit(1);}while(0);/* 简单工厂处…

TDengine安装教程

TDengine安装教程 前言 TDengine的安装十分简单&#xff0c;可以有以下三种安装方式&#xff0c;源码安装、通过Docker容器进行安装、通过安装包进行安装。但是使用源码安装较为复杂&#xff0c;通过docker的方式最为简单&#xff0c;但是需要一定docker相关的知识&#xff0…

C++中size_t的学习

size_t的定义 size_t是一种数据相关的无符号类型&#xff0c;它被设计得足够大以便能够存储内存中任意对象的大小。设计 size_t 就是为了适应多个平台&#xff0c;size_t等效于unsigned short int 或者 unsigned long int 类型&#xff0c;这个过程是动态匹配的。在需要通过数…

策略模式解决商店打折问题

#include <bits/stdc.h> using namespace std; /*策略模式解决商店打折问题*/class Cashsuper { private:/* data */ public:virtual double addcash(double cash) 0;double Getresult(double money){return addcash(money);} };class Cashnormal : public Cashsuper {p…

android 软件首次运行时引导页左右滑动效果

很多手机软件在安装后首次运行都会进入到引导页面&#xff0c;再次运行时会进入到主页面。 多了不说了&#xff0c;先看效果图&#xff1a; 代码如下&#xff1a; main.xml <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:an…

C++中size_type类型详解

介绍 是和string类类型和vector类类型定义相关的类型&#xff0c;用以保存任意string对象或vector对象的长度&#xff0c;标准库类型将size_type定义为unsigned类型string抽象意义是字符串&#xff0c; size&#xff08;&#xff09;的抽象意义是字符串的尺寸&#xff0c; str…

单一职责原则 实现贪吃蛇代码的封装

单一职责原则(SRP),就一个类而言&#xff0c;应该仅有一个引起它 变化的原因。 一个c语言的贪吃蛇代码 如何使用单一职责原则封装成c面向对象呢 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include <wi…

android ProgressBar实现扫描SD卡文件 + SimpleAdapter绑定ListView

代码 activity_main.xml <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_parent"android:layout_height"match_parent"to…

C++标准库函数begin和end函数

主要的目的 为了让指针更加简单、安全&#xff0c;引入了begin和end函数&#xff0c;这两个函数和容器中两个同名的成员函数类似。但是由于数组毕竟不是类类型&#xff0c;因此这两个函数不是成员函数。正确的使用形式就是将数组作为他们的参数int ia[] {0,1,2,3,4,5,6,7,8,9…

dex分包之--------multidex包的配置使用

目录&#xff1a;一、前言二、产生原因三、MultiDex的简要原理四、MultiDex的使用 一、前言 首先说一下我遇到的情况&#xff0c;最近接手了一个项目是在已有的项目里进行更新添加一些功能&#xff0c;然后该项目导了N多的包&#xff0c;在我使用Android Studio的run”App”直…

C++ primer第六章函数的学习

介绍 首先介绍函数的定义和声明&#xff0c;包括如何传入参数以及函数如何返回结果。C语言允许使用重载函数&#xff0c;即几个不同的函数可以使用向同一个名字。所以接下来介绍重载函数的方法&#xff0c;以及编译器选择如何从函数的若干重载的形式中选取一个与调用模板相互匹…

C语言指针作为函数参数 以及智能指针作为函数参数

总所周知指针作为函数参数传递的时候 传递的是指针的拷贝&#xff08;指针也是变量&#xff09; 这里提供四种指针的传递方法 改到实际的指针。 #include <stdio.h> #include <memory> #include <iostream> using namespace std; void test1(char **string)…

Android Studio打包和引用aar

一、简介 Android 库在结构上与 Android 应用模块相同。它可以提供构建应用所需的一切内容&#xff0c;包括源代码、资源文件和 Android 清单。不过&#xff0c;Android 库将编译到您可以用作 Android 应用模块依赖项的 Android 归档 (AAR) 文件&#xff0c;而不是在设备上运行…

C++ primer第六章6.4函数的学习 之函数的重载

6.4 函数的重载 函数的名字相同但是形参的列表不同&#xff0c;将其称之为重载函数 void print(const char *cp); void print(const int *beg,const int * end); void print(const int ia[],size_t size); 形如上面所展现的这样&#xff0c;当调用这些函数的时候&#xff0c;…

C++有限状态机的实现

//待完善 有限状态机是一个很常用的技术&#xff0c;在流程控制和游戏AI中都比较实用&#xff0c;因为状态机编程简单又很符合直觉。与有限状态机类似的是设计模式中的状态模式。本文是参考《Programming Game AI by Example》 一、 记得最开始工作时候也接触过有限状态机&…

手势希尔排序

void shell_sort(int *data, int length){int gap0;int i0,j0;for(gaplength/2;gap>1;gap/2){//组内插入排序for(igap;i<length;i){int temp data[i];for(ji-gap;j>0&&temp<data[j];jj-gap){data[jgap]data[j];}data[jgap]temp;}} }

Android之android.os.Build

一、类概述&#xff1a;从系统属性中提取设备硬件和版本信息。 二、内部类&#xff1a; 1、Build.VERSION 各种版本字符串 2、Build.VERSION_CODES 目前已知的版本代码的枚举类 三、常量&#xff1a;UNKNOWN 当一个版本属性不知道时所设定的值。其字符串值为 “unknown” 。 …

C++ unsigned char*转化为string的形式

unsigned char*转化为string int main(int argc,char **argv){//unsigned char * 转化为string//参考链接 https://www.itdaan.com/tw/4ff531a5e6651468a5b7c6d95927ba3dunsigned char *foo;unsigned char str[] "Hello world";string strHH;foo str;strHH.append…