title: Generate `VertexId` from pairs of `String`
body: <p>I'm using GraphX to process some graph data on Spark. The input data is given as <code>RDD[(String, String)]</code>. I used the following snippet to map <code>String</code> to <code>VertexId</code> and build the graph.</p>
  
  <pre class="lang-scala prettyprint-override"><code>val input: RDD[(String, String)] = ...
  
  val vertexIds = input.map(_._1)
                       .union(input.map(_._2))
                       .distinct()
                       .zipWithUniqueId()
                       .cache()
  
  val edges = input.join(vertexIds)
                   .map { case (u, (v, uid)) =&gt; (v, uid) }
                   .join(vertexIds)
                   .map { case (v, (uid, vid)) =&gt; Edge(uid, vid, 1) }
  
  val graph = Graph(vertexIds.map { case (v, vid) =&gt; (vid, v) }, edges )
  </code></pre>
  
  <p>When I did a spot check to see the top 1000 highest degree nodes, I found the result of GraphX is different from the original input. Here's how I dump the high degree node</p>
  
  <pre class="lang-scala prettyprint-override"><code>graph.outerJoinVertices(graph.outDegrees) {
    (_, vdata, deg) =&gt; (deg.getOrElse(0L), vdata)
  }.vertices.map(_._2).top(1000).saveTo(....)
  </code></pre>
  
  <p>I suspect <code>.zipWithUniqueId</code> gives unstable ids for each evaluation. I tried </p>
  
  <ul>
  <li>insert <code>vertexIds.count()</code> to force materialization so that <code>vertexIds</code> doesn't get reevaluated.</li>
  <li>insert <code>.sortBy(...).zipWithUniqueId()</code> to make sure the ordering is the same.</li>
  </ul>
  
  <p>Neither of them solves the problem. The results of top 1000 degree nodes differ slightly for each run.</p>