Skip to content

Pinning an MFS folder takes a lot of IO #8988

Open
@RubenKelevra

Description

@RubenKelevra

Checklist

Installation method

built from source

Version

go-ipfs version: 0.14.0-dev-a72753bad-dirty
Repo version: 12
System version: amd64/linux
Golang version: go1.18.2

Config

{
  "API": {
    "HTTPHeaders": {}
  },
  "Addresses": {
    "API": "/ip4/127.0.0.1/tcp/5001",
    "Announce": [],
    "AppendAnnounce": null,
    "Gateway": "/ip4/127.0.0.1/tcp/80",
    "NoAnnounce": [
      "/ip4/10.0.0.0/ipcidr/8",
      "/ip4/100.64.0.0/ipcidr/10",
      "/ip4/169.254.0.0/ipcidr/16",
      "/ip4/172.16.0.0/ipcidr/12",
      "/ip4/192.0.0.0/ipcidr/24",
      "/ip4/192.0.0.0/ipcidr/29",
      "/ip4/192.0.0.8/ipcidr/32",
      "/ip4/192.0.0.170/ipcidr/32",
      "/ip4/192.0.0.171/ipcidr/32",
      "/ip4/192.0.2.0/ipcidr/24",
      "/ip4/192.168.0.0/ipcidr/16",
      "/ip4/198.18.0.0/ipcidr/15",
      "/ip4/198.51.100.0/ipcidr/24",
      "/ip4/203.0.113.0/ipcidr/24",
      "/ip4/240.0.0.0/ipcidr/4",
      "/ip6/100::/ipcidr/64",
      "/ip6/2001:2::/ipcidr/48",
      "/ip6/2001:db8::/ipcidr/32",
      "/ip6/fc00::/ipcidr/7",
      "/ip6/fe80::/ipcidr/10"
    ],
    "Swarm": [
      "/ip4/0.0.0.0/tcp/443",
      "/ip6/::/tcp/443",
      "/ip4/0.0.0.0/udp/443/quic",
      "/ip6/::/udp/443/quic"
    ]
  },
  "AutoNAT": {
    "ServiceMode": "disabled"
  },
  "Bootstrap": [
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
    "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
    "/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"
  ],
  "DNS": {
    "Resolvers": null
  },
  "Datastore": {
    "BloomFilterSize": 0,
    "GCPeriod": "1h",
    "HashOnRead": false,
    "Spec": {
      "mounts": [
        {
          "child": {
            "path": "blocks",
            "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
            "sync": false,
            "type": "flatfs"
          },
          "mountpoint": "/blocks",
          "prefix": "flatfs.datastore",
          "type": "measure"
        },
        {
          "child": {
            "compression": "none",
            "path": "datastore",
            "type": "levelds"
          },
          "mountpoint": "/",
          "prefix": "leveldb.datastore",
          "type": "measure"
        }
      ],
      "type": "mount"
    },
    "StorageGCWatermark": 90,
    "StorageMax": "500GB"
  },
  "Discovery": {
    "MDNS": {
      "Enabled": false,
      "Interval": 10
    }
  },
  "Experimental": {
    "AcceleratedDHTClient": true,
    "FilestoreEnabled": false,
    "GraphsyncEnabled": false,
    "Libp2pStreamMounting": false,
    "P2pHttpProxy": false,
    "StrategicProviding": false,
    "UrlstoreEnabled": false
  },
  "Gateway": {
    "APICommands": [],
    "HTTPHeaders": {
      "Access-Control-Allow-Headers": [
        "X-Requested-With",
        "Range",
        "User-Agent"
      ],
      "Access-Control-Allow-Methods": [
        "GET"
      ],
      "Access-Control-Allow-Origin": [
        "*"
      ]
    },
    "NoDNSLink": false,
    "NoFetch": false,
    "PathPrefixes": [],
    "PublicGateways": null,
    "RootRedirect": "",
    "Writable": false
  },
  "Identity": {
    "PeerID": "QmVoV4RiGLcxAfhA181GXR867bzVxmRTWwaubvhUyFrBwB"
  },
  "Internal": {
    "Bitswap": {
      "EngineBlockstoreWorkerCount": 4,
      "EngineTaskWorkerCount": 2,
      "TaskWorkerCount": 4
    },
    "UnixFSShardingSizeThreshold": "1MB"
  },
  "Ipns": {
    "RecordLifetime": "4h",
    "RepublishPeriod": "15m",
    "ResolveCacheSize": 2048,
    "UsePubsub": true
  },
  "Migration": {
    "DownloadSources": null,
    "Keep": ""
  },
  "Mounts": {
    "FuseAllowOther": false,
    "IPFS": "/ipfs",
    "IPNS": "/ipns"
  },
  "Peering": {
    "Peers": null
  },
  "Pinning": {},
  "Plugins": {
    "Plugins": null
  },
  "Provider": {
    "Strategy": ""
  },
  "Pubsub": {
    "DisableSigning": false,
    "Enabled": true,
    "Router": "gossipsub"
  },
  "Reprovider": {
    "Interval": "12h",
    "Strategy": "all"
  },
  "Routing": {
    "Type": "dht"
  },
  "Swarm": {
    "AddrFilters": [
      "/ip4/10.0.0.0/ipcidr/8",
      "/ip4/100.64.0.0/ipcidr/10",
      "/ip4/169.254.0.0/ipcidr/16",
      "/ip4/172.16.0.0/ipcidr/12",
      "/ip4/192.0.0.0/ipcidr/24",
      "/ip4/192.0.0.0/ipcidr/29",
      "/ip4/192.0.0.8/ipcidr/32",
      "/ip4/192.0.0.170/ipcidr/32",
      "/ip4/192.0.0.171/ipcidr/32",
      "/ip4/192.0.2.0/ipcidr/24",
      "/ip4/192.168.0.0/ipcidr/16",
      "/ip4/198.18.0.0/ipcidr/15",
      "/ip4/198.51.100.0/ipcidr/24",
      "/ip4/203.0.113.0/ipcidr/24",
      "/ip4/240.0.0.0/ipcidr/4",
      "/ip6/100::/ipcidr/64",
      "/ip6/2001:2::/ipcidr/48",
      "/ip6/2001:db8::/ipcidr/32",
      "/ip6/fc00::/ipcidr/7",
      "/ip6/fe80::/ipcidr/10"
    ],
    "ConnMgr": {
      "GracePeriod": "3m",
      "HighWater": 1200,
      "LowWater": 600,
      "Type": "basic"
    },
    "DisableBandwidthMetrics": false,
    "DisableNatPortMap": true,
    "EnableHolePunching": false,
    "RelayClient": {
      "Enabled": false
    },
    "RelayService": {
      "ConnectionDataLimit": 268435456,
      "ConnectionDurationLimit": "24h",
      "Enabled": true,
      "MaxCircuits": 100,
      "MaxReservations": 1024,
      "MaxReservationsPerASN": 100,
      "MaxReservationsPerIP": 1,
      "MaxReservationsPerPeer": 1
    },
    "Transports": {
      "Multiplexers": {},
      "Network": {},
      "Security": {}
    }
  }
}

Description

I'm using ipfs-cluster on an ipfs node with around 500 GB data in the MFS in a lot of smallish files.

I do update the files with normal ipfs files operations like ipfs files rm and ipfs files cp.

Afterwards the folder is added to the clusterpin, so the already fully stored MFS folder is then pinned locally again, by the ipfs-cluster-daemon.

I run the ipfs-cluster-ctl pin update $oldcid $newcid command for this, to only push the data to cluster members which already hold the old pin, to avoid shuffling the 60-100 GB folders around in the cluster.

The "null" pin operation takes a very long time and creates a lot of reading IO – for no apparent benefit. The data is already stored in the MFS and would just need to be marked as "pinned" additionally, without checking each and every block for existence (or whatever IPFS does in this case).

I see loads of up to 60 on the machine:

Log in to system  : odin.pacman.store
Operating system  : ArchLinux
Kernel version    : 5.17.5-arch1-1
No. processors    : 10
Main memory       : 32104M
Machine load      : 53,91, 58,76, 61,60
Machine uptime    : 13 days 6:54

Screenshot_20220522_071929

Screenshot_20220522_072211

Screenshot_20220522_072310

Screenshot_20220522_072407

Screenshot_20220522_072956

What I tried to work around this:

I reduced the IO priority of the ipfs daemon in the systemd unit file:

IOSchedulingClass=idle
IOSchedulingPriority=1

This made the system more responsive again.

I changed the bitswap internal values to the following:

    "Bitswap": {
      "EngineBlockstoreWorkerCount": 4,
      "EngineTaskWorkerCount": 2,
      "TaskWorkerCount": 4
    },

Overall, this doesn't really help (if it does do anything (yet)).

(The graphs above are already with these changes)

Edit: Just to confirm: The GC is not running. I invoke the GC manually when necessary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low: Not priority right nowkind/bugA bug in existing code (including security flaws)need/triageNeeds initial labeling and prioritizationtopic/MFSTopic MFS

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions