[SPARK-3453] Netty-based BlockTransferService

I tested the new network shuffle code. This network shuffle code can support ~ 1GB/s per node network speed while producing almost no garbage that would trigger gc.

Issues addressed in this pull request:
- SPARK-3453: Refactor Netty module to use BlockTransferService interface
- SPARK-3016: Block upload
- SPARK-3018: Release all buffers upon task completion/failure
- SPARK-3002: Create a connection pool and reuse clients across different threads
- SPARK-3017: Integration tests and unit tests for connection failures
- SPARK-3049: Make sure client doesn't block when server/connection has error(s)
- SPARK-3502: SO_RCVBUF and SO_SNDBUF should be bootstrap childOption, not option
- SPARK-3503: Disable thread local cache in PooledByteBufAllocator

Review guide:
- server/client protocol is defined in protocol.scala
- please look closely at ShuffleBlockFetcherIterator, in particular, parts related to reference counting and cleanup of buffers

Things that should be done in separate PRs:
- SASL security support
- (maybe) use BlockID instead of String for stronger types in block ids

Thanks to @normanmaurer who reviewed the code offline with me.
It'd be better if we could go ahead and make the config stable, it's always painful for people to update later. Even if it's just like

```scala
val blockTransferService = conf.getString("spark.shuffle.transferService", "NIO") match {
  case "NETTY" => new NettyBlockTransferService(conf)
  case "NIO" => new NioBlockTransferService(conf, securityManager)
  case s => throw new UnsupportedOperationException("Unknown transfer service: " + s)
}
```

Potentially less pain for when we address the TODO at a later date.