Skip to content

Commit f1836b8

Browse files
authored
feat: Add topology-provider (#28)
* feat: Add topology-provider * changelog * fix yaml * fix yaml part 2
1 parent 9b9806a commit f1836b8

File tree

11 files changed

+1053
-2
lines changed

11 files changed

+1053
-2
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [Unreleased]
6+
7+
### Added
8+
9+
- Add topology-provider from https://github.com/stackabletech/hdfs-topology-provider ([#28]).
10+
11+
[#28]: https://github.com/stackabletech/hdfs-utils/pull/28

README.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ This project contains multiple plugins for Apache Hadoop, which are intended to
66

77
1. OpenPolicyAgent (OPA) authorizer: For every action performed in HDFS an OPA instance is asked if the user is allowed to perform the action.
88
2. GroupMapper: It can look up group memberships for users from an OPA instance.
9-
3. Not (yet?) in this repository is a [TopologyProvider](https://github.com/stackabletech/hdfs-topology-provider/).
9+
3. TopologyProvider: It is used to feed information from Kubernetes into the HDFS rack awareness functionality.
1010

1111
## Installation
12+
1213
Run `mvn package` and put the resulting `target/hdfs-utils-*.jar` file on your HDFS classpath.
1314
The easiest way to achieve this is to put it in the directory `/stackable/hadoop/share/hadoop/tools/lib/`.
1415
The Stackable HDFS already takes care of this, you don't need to do anything in this case.
@@ -650,3 +651,64 @@ and the Hadoop logs will show that the lookup has taken place:
650651
- Groups for [nn]: [[admin, superuser]]
651652
```
652653

654+
## Network Topology Provider
655+
656+
Hadoop supports a concept called [rack awareness](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/RackAwareness.html) (lately also often called topology awareness).
657+
658+
Historically this has been used to distinguish racks, datacenters and the like and often been read from a manually updated topology file or similar solutions.
659+
660+
In Kubernetes, the most commonly used mechanism for topology awareness are labels - mostly labels set on the Kubernetes nodes.
661+
The most prevalent example for this is the node label [topology.kubernetes.io/zone](https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone) which often refers to availability zones in cloud providers or similar things.
662+
663+
The purpose of this tool is to feed information from Kubernetes into the HDFS rack awareness functionality.
664+
In order to do this, it implements the Hadoop interface `org.apache.hadoop.net.DNSToSwitchMapping` which then allows this tool to be configured on the NameNode via the parameter `net.topology.node.switch.mapping.impl`.
665+
666+
The topology provider watches all HDFS pods deployed by Stackable and Kubernetes nodes and keeps an in memory cache of the current state of these objects.
667+
From this state store the tool can then calculate rack IDs for nodes that HDFS asks for without needing to talk to the api-server and incurring an extra network round-trip.
668+
669+
Results are cached for a configurable amount of time and served from the cache if present.
670+
671+
In a Kubernetes environment it is likely that the majority of writes will not come from the DataNodes themselves, but rather from other processes such as Spark executors writing data to HDFS. The NameNode passes these on to the topology provider to request the rack ID i.e. it provides the IP addresses of whichever pods are doing the writing. If a datanode resides on the same Kubernetes node as one of these pods, then this datanode is used for label resolution for that pod.
672+
673+
## Configuration
674+
675+
Configuration of the tool happens via environment variables, as shown below:
676+
677+
### TOPOLOGY_LABELS
678+
679+
A semicolon separated list of labels that should be used to build a rack id for a datanode.
680+
681+
A label is specified as `[node|pod]:<labelname>`
682+
683+
Some examples:
684+
685+
| Definition | Resolved to |
686+
|----------------------------------|------------------------------------------------------------------------------------------------------|
687+
| node:topology.kubernetes.io/zone | The value of the label 'topology.kubernetes.io/zone' on the node to which the pod has been assigned. |
688+
| pod:app.kubernetes.io/role-group | The value of the label 'app.kubernetes.io/role-group' on the datanode pod. |
689+
690+
Multiple levels of labels can be combined (up to MAX_TOPOLOGY_LABELS levels) by separating them with a semicolon:
691+
692+
So for example `node:topology.kubernetes.io/zone;pod:app.kubernetes.io/role-group` would resolve to `/<value of label topology.kubernetes.io/zone on the node>/<value of label app.kubernetes.io/role-group on the pod>`.
693+
694+
### TOPOLOGY_CACHE_EXPIRATION_SECONDS
695+
696+
Default: 5 Minutes
697+
698+
The default time for which rack ids are cached, HDFS can influence caching, as the provider offers methods to invalidate the cache, so this is not a totally _reliable_ value, as there are external factors not under the control of this tool.
699+
700+
### MAX_TOPOLOGY_LEVELS
701+
702+
Default: 2
703+
704+
The maximum number of levels that can be specified to build a rack id from.
705+
706+
While this can be changed, HDFS probably only supports a maximum of two levels, so it is not recommended to change the default for this setting.
707+
708+
## Testing
709+
710+
There are currently no unit tests.
711+
712+
CRDs for spinning up test infrastructure are provided in `test/stack`.
713+
714+
The actual testing for this happens in the integration tests of the HDFS operator.

pom.xml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,26 @@
7575
<dependency>
7676
<groupId>com.fasterxml.jackson.core</groupId>
7777
<artifactId>jackson-databind</artifactId>
78-
<version>2.12.7.1</version>
78+
<version>2.17.1</version>
7979
<scope>provided</scope>
8080
</dependency>
81+
<!-- Needed by topology-provider -->
82+
<dependency>
83+
<groupId>com.github.ben-manes.caffeine</groupId>
84+
<artifactId>caffeine</artifactId>
85+
<version>3.1.8</version>
86+
</dependency>
87+
<dependency>
88+
<groupId>io.fabric8</groupId>
89+
<artifactId>kubernetes-client</artifactId>
90+
<version>6.13.1</version>
91+
</dependency>
92+
<dependency>
93+
<groupId>io.fabric8</groupId>
94+
<artifactId>kubernetes-client-api</artifactId>
95+
<version>6.13.1</version>
96+
</dependency>
97+
<!-- End of needed by topology-provider -->
8198
<dependency>
8299
<groupId>junit</groupId>
83100
<artifactId>junit</artifactId>

0 commit comments

Comments
 (0)