av9ash/GitBugs huggingface dataset:
Bug: kubernetes executor pod unable to access secure hdfs
Status: Open | Priority: Major | Resolution: 
Created: 29/Jan/21 18:41
Affects Version/s: 3.0.1

Steps to reproduce
 # Configure secure HDFS(kerberos) cluster running as containers in kubernetes.
 # Configure KDC on centos and create keytab for user principal hdfs, in hdfsuser.keytab.
 # Genearte spark image(v3.0.1), to spawn as container out of spark image.
 # Inside spark container, run export HADOOP_CONF_DIR=/etc/hadoop/conf/ with core-site.xml configuration as below 
 !image-2021-01-30-00-13-18-234.png!
 # Create configmap kbr-conf 
 !image-2021-01-30-00-14-14-329.png!
 # Run the command /opt/spark/bin/spark-submit \
 --deploy-mode client \
 --executor-memory 1g\
 --executor-memory 1g\
 --executor-cores 1\
 --class org.apache.spark.examples.HdfsTest \
 --conf spark.kubernetes.namespace=arcsight-installer-lh7fm\
 --master k8s://[https://172.17.17.1:443|https://172.17.17.1/] \
 --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \
 --conf spark.app.name=spark-hdfs \
 --conf spark.executer.instances=1 \
 --conf spark.kubernetes.node.selector.spark=yes\
 --conf spark.kubernetes.node.selector.Worker=label\
 --conf spark.kubernetes.container.image=manohar/spark:v3.0.1 \
 --conf spark.kubernetes.kerberos.enabled=true \
 --conf spark.kubernetes.kerberos.krb5.configMapName=krb5-conf \
 --conf spark.kerberos.keytab=/data/hdfsuser.keytab \
 --conf spark.kerberos.principal=hdfs@DOM047600.LAB \
 local:///opt/spark/examples/jars/spark-examples_2.12-3.0.1.jar \
 hdfs://hdfs-namenode:30820/staging-directory.
 # On running this command driver is able to connect hdfs with kerberos but execurtor fails to connect to secure hdfs and below is the logs 
!image-2021-01-30-00-34-05-946.png!
 # Some of observation
 ## In Client mode, --conf spark.kubernetes.hadoop.configMapName=hadoop-conf as not effect only works after HADOOP_CONF_DIR is set. Below was the contents of hadoop-conf configmap.
 !image-2021-01-30-00-20-54-620.png!
 ## Ran the command in cluster mode as well, in cluster mode also executor could not connect to secure hdfs.
Bug: Block `count(table.*)` to follow ANSI standard and other SQL engines
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 22/Jan/21 03:51
Affects Version/s: 3.2.0

In spark, the count(table.*) may cause very weird result, for example:

select count(*) from (select 1 as a, null as b) t;

output: 1

select count(t.*) from (select 1 as a, null as b) t;

output: 0

 

After checking the ANSI standard, count(*) is always treated as count(1) while count(t.*) is not allowed. What's more, this is also not allowed by common databases, e.g. MySQL, oracle.
Bug: NPE for char padding in binary comparison
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 26/Jan/21 02:56
Affects Version/s: 3.1.0

test("char type comparison: top-level columns") {
    withTable("t") {
      sql(s"CREATE TABLE t(c1 CHAR(2), c2 CHAR(5)) USING $format")
      sql("INSERT INTO t VALUES ('a', 'a')")
      testConditions(spark.table("t"), Seq(
        ("c1 = 'a'", true),
        ("'a' = c1", true),
        ("c1 = 'a  '", true),
        ("c1 > 'a'", false),
        ("c1 IN ('a', 'b')", true),
        ("c1 = c2", true),
        ("c1 < c2", false),
        ("c1 IN (c2)", true),
       {color:red} ("c1 = null", false))){color}
    }
  }

the red one will raise NPE
Bug: v2 ALTER TABLE .. DROP PARTITION does not remove data from dropped partition
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 04/Jan/21 12:41
Affects Version/s: 3.2.0

The test fails:
{code:scala}
  test("SPARK-XXXXX: don not return data from dropped partition") {
    withNamespaceAndTable("ns", "tbl") { t =>
      sql(s"CREATE TABLE $t (id int, part int) $defaultUsing PARTITIONED BY (part)")
      sql(s"INSERT INTO $t PARTITION (part=0) SELECT 0")
      sql(s"INSERT INTO $t PARTITION (part=1) SELECT 1")
      QueryTest.checkAnswer(sql(s"SELECT * FROM $t"), Seq(Row(0, 0), Row(1, 1)))
      sql(s"ALTER TABLE $t DROP PARTITION (part=0)")
      QueryTest.checkAnswer(sql(s"SELECT * FROM $t"), Seq(Row(1, 1)))
    }
  }
{code}
on the last check with:
{code}
== Results ==
!== Correct Answer - 1 ==   == Spark Answer - 2 ==
!struct<>                   struct<id:int,part:int>
![1,1]                      [0,0]
!                           [1,1]
{code}
Bug: Avoid migrating un-needed shuffle files
Status: Open | Priority: Major | Resolution: 
Created: 28/Jan/21 20:04
Affects Version/s: 3.1.0

In Spark 3.1 we introduced shuffle migrations. However, it is possible that a shuffle file will still exist after it is no longer needed. I've only observed this in a back port branch with SQL, so I'll do some more digging.
Bug: Combine StateStoreMetrics should not override StateStoreCustomMetric
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 27/Jan/21 21:27
Affects Version/s: 2.3.4

For stateful join in structured streaming, we need to combine StateStoreMetrics from both left and right side. Currently we simply take arbitrary one from custom metrics with same name from left and right. By doing this we miss half of metric number.
Bug: Vectorized reader support column index
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 29/Jan/21 08:29
Affects Version/s: 3.2.0

[InternalParquetRecordReader|https://github.com/apache/parquet-mr/blob/apache-parquet-1.11.1/parquet-hadoop/src/main/java/org/apache/parquet/hadoop/InternalParquetRecordReader.java] has support column index.
Vectorized reader also should support it.
Bug: Unify v1 and v2 ALTER TABLE .. RECOVER PARTITIONS tests
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 09/Jan/21 17:13
Affects Version/s: 3.2.0

Extract ALTER TABLE .. RECOVER PARTITIONS tests to the common place to run them for V1 and v2 datasources. Some tests can be places to V1 and V2 specific test suites.
Bug: Cache lookup doesn't work in certain cases
Status: Resolved | Priority: Major | Resolution: Duplicate
Created: 14/Jan/21 03:13
Affects Version/s: 3.1.0

Currently, caching a temporary or permenant view doesn't work in certain cases. For instance, in the following:
{code:sql}
CREATE TABLE t (key bigint, value string) USING parquet
CREATE VIEW v1 AS SELECT key FROM t
CACHE TABLE v1
SELECT key FROM t
{code}
The last SELECT query will hit the cached {{v1}}. On the other hand:
{code:sql}
CREATE TABLE t (key bigint, value string) USING parquet
CREATE VIEW v1 AS SELECT key FROM t ORDER by key
CACHE TABLE v1
SELECT key FROM t ORDER BY key
{code}
The SELECT won't hit the cache.

It seems this is related to {{EliminateView}}. In the second case, it will insert an extra project operator which makes the comparison on canonicalized plan during cache lookup fail.
Bug: View subqueries in aggregate's grouping expression fail during the analysis check
Status: Resolved | Priority: Major | Resolution: Not A Problem
Created: 26/Jan/21 18:00
Affects Version/s: 3.1.0

To repro:

{code:java}
sql("create temporary view ta(a, b) as select 1, 2")
sql("create temporary view tc(c, d) as select 1, 2")
sql("select a, (select sum(d) from tc where a = c) sum_d from ta group by 1, 2").show
{code}
fails with:

{code:java}
This method should not be called in the analyzer
java.lang.RuntimeException: This method should not be called in the analyzer
	at org.apache.spark.sql.catalyst.plans.logical.AnalysisHelper.assertNotAnalysisRule(AnalysisHelper.scala:159)
	at org.apache.spark.sql.catalyst.plans.logical.AnalysisHelper.assertNotAnalysisRule$(AnalysisHelper.scala:155)
	at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan.assertNotAnalysisRule(LogicalPlan.scala:29)
	at org.apache.spark.sql.catalyst.plans.logical.AnalysisHelper.transformUp(AnalysisHelper.scala:179)
	at org.apache.spark.sql.catalyst.plans.logical.AnalysisHelper.transformUp$(AnalysisHelper.scala:178)
	at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan.transformUp(LogicalPlan.scala:29)
	at org.apache.spark.sql.catalyst.analysis.EliminateView$.apply(view.scala:56)
	at org.apache.spark.sql.catalyst.plans.logical.View.doCanonicalize(basicLogicalOperators.scala:485)
	at org.apache.spark.sql.catalyst.plans.logical.View.doCanonicalize(basicLogicalOperators.scala:458)
	at org.apache.spark.sql.catalyst.plans.QueryPlan.canonicalized$lzycompute(QueryPlan.scala:373)
	at org.apache.spark.sql.catalyst.plans.QueryPlan.canonicalized(QueryPlan.scala:372)
	at org.apache.spark.sql.catalyst.plans.logical.SubqueryAlias.doCanonicalize(basicLogicalOperators.scala:953)
	at org.apache.spark.sql.catalyst.plans.logical.SubqueryAlias.doCanonicalize(basicLogicalOperators.scala:936)
	at org.apache.spark.sql.catalyst.plans.QueryPlan.canonicalized$lzycompute(QueryPlan.scala:373)
	at org.apache.spark.sql.catalyst.plans.QueryPlan.canonicalized(QueryPlan.scala:372)
	at org.apache.spark.sql.catalyst.plans.QueryPlan.$anonfun$doCanonicalize$1(QueryPlan.scala:387)
	at scala.collection.immutable.List.map(List.scala:293)
...
{code}

This works fine in Spark 3.0, and the issue seems to be brought by https://github.com/apache/spark/pull/30567, which introduced View.doCanonicalize()
Bug: LOAD DATA doesn't refresh v1 table cache
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 23/Jan/21 17:58
Affects Version/s: 3.0.2

The example below portraits the issue:
1. Create a source table:
{code:sql}
spark-sql> CREATE TABLE src_tbl (c0 int, part int) USING hive PARTITIONED BY (part);
spark-sql> INSERT INTO src_tbl PARTITION (part=0) SELECT 0;
spark-sql> SHOW TABLE EXTENDED LIKE 'src_tbl' PARTITION (part=0);
default	src_tbl	false	Partition Values: [part=0]
Location: file:/Users/maximgekk/proj/load-data-refresh-cache/spark-warehouse/src_tbl/part=0
...
{code}
2. Load data from the source table to a cached destination table:
{code:sql}
spark-sql> CREATE TABLE dst_tbl (c0 int, part int) USING hive PARTITIONED BY (part);
spark-sql> INSERT INTO dst_tbl PARTITION (part=1) SELECT 1;
spark-sql> CACHE TABLE dst_tbl;
spark-sql> SELECT * FROM dst_tbl;
1	1
spark-sql> LOAD DATA LOCAL INPATH '/Users/maximgekk/proj/load-data-refresh-cache/spark-warehouse/src_tbl/part=0' INTO TABLE dst_tbl PARTITION (part=0);
spark-sql> SELECT * FROM dst_tbl;
1	1
{code}
The last query does not show recently loaded data from the source table.
Bug: TRUNCATE TABLE resets stats for non-empty v1 table
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 26/Jan/21 16:41
Affects Version/s: 3.0.2

The example below portraits the issue:
{code:sql}
spark-sql> CREATE TABLE tbl (c0 int, part int) PARTITIONED BY (part);
spark-sql> INSERT INTO tbl PARTITION (part=0) SELECT 0;
spark-sql> INSERT INTO tbl PARTITION (part=1) SELECT 1;
spark-sql> ANALYZE TABLE tbl COMPUTE STATISTICS;
spark-sql> DESCRIBE TABLE EXTENDED tbl;
...
Statistics	4 bytes, 2 rows
...
{code}
Let's truncate one partition:
{code:sql}
spark-sql> TRUNCATE TABLE tbl PARTITION (part=1);
spark-sql> DESCRIBE TABLE EXTENDED tbl;
...
Statistics	0 bytes, 0 rows
...
spark-sql> SELECT * FROM tbl;
0	0
{code}
*The last query returns a row but stats show 0 rows. *
Bug: Remove the Scala function version of regexp_extract_all
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 26/Jan/21 12:27
Affects Version/s: 3.2.0

SPARK-24884 implement regexp_extract_all and added the scala function version of it.
According https://github.com/apache/spark/blob/master/sql/core/src/main/scala/org/apache/spark/sql/functions.scala#L41-L59, it seems good for remove the scala function version. Although I think is regexp_extract_all is very useful, if we just reference the description.
Bug: Expose regexp_extract_all to PySpark
Status: Resolved | Priority: Major | Resolution: Won't Fix
Created: 24/Jan/21 12:16
Affects Version/s: 3.1.2

I've often come across use cases for regexp_extract_all while working with PySpark code, and UDFs implementing this functionality are very poorly performant. Given the size of the PySpark community, it would be very valuable to have it exposed in the PySpark API.

All the rationale for why regexp_extract_all is useful is expressed SPARK-24884.
Bug: Update the spark libraries to expose Java module names
Status: Open | Priority: Major | Resolution: 
Created: 26/Jan/21 10:06
Affects Version/s: 3.0.1

Trying to derive the automatic module name for any of the spark related artifacts currently fails with the following error. 

{\{naman.nigam jar --file=/Users/naman.nigam/.m2/repository/org/apache/spark/spark-core_2.12/3.1.0/spark-core_2.12-3.1.0.jar --describe-module}}

{{Unable to derive module descriptor for: /Users/naman.nigam/.m2/repository/org/apache/spark/spark-core_2.12/3.1.0/spark-core_2.12-3.1.0.jar}}{{spark.core.2.12: Invalid module name: '2' is not a Java identifier}}

 

I was hoping there could be an improvement in this direction such that the artifacts could be used in the modularised applications even if they are not themself modularised.

 

This relates to a previous bug reported under https://issues.apache.org/jira/browse/SPARK-23543, but it has been unfortunately closed as Incomplete and there seems no other way to track the progress that Spark is planning to make in this direction.
Bug: Use getPartitionByNames to filter partition to avoid partition scan
Status: In Progress | Priority: Major | Resolution: 
Created: 26/Jan/21 09:02
Affects Version/s: 2.4.0

In HiveShim, `getPartitionByFilters` will lead parttion scan in special , ec:  concat(dt, phour)='2021-01-26 18', the `convertFilters` can't explain this case to filter partition.

In this issue case , It will `getAllPartitionName` to fetch all partition, and will calc local to filter all quafilied partition, and use `getPartitionByNames` to fetch partition detail info as last.
Bug: NPE for static partion with null in InsertIntoHadoopFsRelationCommand
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 25/Jan/21 11:04
Affects Version/s: 3.0.1

a test case
{code:java}
 test("NPE") {
    withTable("t") {
      sql(s"CREATE TABLE t(i STRING, c string) USING $format PARTITIONED BY (c)")
      sql("INSERT OVERWRITE t PARTITION (c=null) VALUES ('1')")
      checkAnswer(spark.table("t"), Row("1", null))
    }
  }
{code}
Bug: Move char padding to write side
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 21/Jan/21 14:16
Affects Version/s: 3.1.0

On the read side, the char length check and padding bring issues to CBO and PPD and other issues to the catalyst.

It's more reasonable to do it on the write side,  as Spark doesn't take full control of the storage layer.



https://issues.apache.org/jira/browse/HIVE-13618

For varchar and string, the below case still exists for the limitation of Hive metastore
For char, we now write fixed-length values, the issue should be fixed

{code:java}
  test("SPARK-34192: Know issue of hive for tailing spaces") {
    // https://issues.apache.org/jira/browse/HIVE-13618
    // Trailing spaces in partition column will be treated differently
    // This is because Mysql and Derby(used in tests) considers 'a' = 'a '
    // whereas others like (Postgres, Oracle) doesn't exhibit this problem.
    Seq("char(5)", "string", "VARCHAR(5)").foreach { typ =>
      withTable("t") {
        sql(s"CREATE TABLE t(i STRING, c $typ) USING $format PARTITIONED BY (c)")
        sql(s"INSERT INTO t VALUES ('1', 'a ')")
        val e = intercept[AnalysisException](sql(s"INSERT INTO t VALUES ('1', 'a  ')"))
        assert(e.getMessage.contains("Expecting a partition with name c=a  ,"))
      }
    }
  }

{code}
Bug: [AVRO] Respect case sensitivity when performing Catalyst-to-Avro field matching
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 15/Jan/21 22:19
Affects Version/s: 2.4.0

Spark SQL is normally case-insensitive (by default), but currently when {{AvroSerializer}} and {{AvroDeserializer}} perform matching between Catalyst schemas and Avro schemas, the matching is done in a case-sensitive manner. So for example the following will fail:
{code}
      val avroSchema =
        """
          |{
          |  "type" : "record",
          |  "name" : "test_schema",
          |  "fields" : [
          |    {"name": "foo", "type": "int"},
          |    {"name": "BAR", "type": "int"}
          |  ]
          |}
      """.stripMargin
      val df = Seq((1, 3), (2, 4)).toDF("FOO", "bar")

      df.write.option("avroSchema", avroSchema).format("avro").save(savePath)
{code}
The same is true on the read path, if we assume {{testAvro}} has been written using the schema above, the below will fail to match the fields:
{code}
df.read.schema(new StructType().add("FOO", IntegerType).add("bar", IntegerType))
  .format("avro").load(testAvro)
{code}
Bug: Improve error message when folks try and install in Python 2
Status: Resolved | Priority: Major | Resolution: Won't Fix
Created: 21/Jan/21 20:08
Affects Version/s: 3.1.0

Current error message:

 
{code:java}
Processing ./pyspark-3.1.1.tar.gz
    ERROR: Command errored out with exit status 1:
     command: /tmp/py3.1/bin/python2 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-req-build-lmlitE/setup.py'"'"'; __file__='"'"'/tmp/pip-req-build-lmlitE/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-W1BsIL
         cwd: /tmp/pip-req-build-lmlitE/
    Complete output (6 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-req-build-lmlitE/setup.py", line 31
        file=sys.stderr)
            ^
    SyntaxError: invalid syntax
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.{code}
Bug: Keep dependants cached while refreshing v1 tables
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 16/Jan/21 14:57
Affects Version/s: 3.2.0

Keeping dependants cached while refreshing v1 tables should allow to improve user experience with table/view caching. For example, let's imagine that an user has cached v1 table and cached view based on the table. And the user passed the table to external library which drops/renames/adds partitions in the v1 table. Unfortunately, the user gets the view uncached after that even he/she hasn't uncached the view explicitly.
Bug: Provide async variants for Dataset APIs
Status: Open | Priority: Major | Resolution: 
Created: 11/Jan/21 23:37
Affects Version/s: 3.0.1

Spark RDDs have async variants such as `collectAsync`, which comes handy when we want to cancel a job. However, Dataset APIs are lacking such APIs, which makes it very painful to cancel a Dataset/SQL job.

 

The proposed change was to add async variants so that we can directly cancel a Dataset/SQL query via a future programmatically.
Bug: DSv2: `ALTER TABLE .. ADD PARTITION` does not refresh table cache
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 18/Jan/21 07:44
Affects Version/s: 3.2.0

For example, the test below:
{code:scala}
  test("SPARK-XXXXX: refresh cache in partition adding") {
    withNamespaceAndTable("ns", "tbl") { t =>
      sql(s"CREATE TABLE $t (part int) $defaultUsing PARTITIONED BY (part)")
      sql(s"ALTER TABLE $t ADD PARTITION (part=0)")
      assert(!spark.catalog.isCached(t))
      sql(s"CACHE TABLE $t")
      assert(spark.catalog.isCached(t))
      checkAnswer(sql(s"SELECT * FROM $t"), Row(0))

      sql(s"ALTER TABLE $t ADD PARTITION (part=1)")
      assert(spark.catalog.isCached(t))
      checkAnswer(sql(s"SELECT * FROM $t"), Seq(Row(0), Row(1)))
    }
  }
{code}
fails with;
{code}
!== Correct Answer - 2 ==   == Spark Answer - 1 ==
!struct<>                   struct<part:int>
 [0]                        [0]
![1]                        
    
       
ScalaTestFailureLocation: org.apache.spark.sql.QueryTest$ at (QueryTest.scala:243)
{code}
because the command doesn't refresh the cache.
Bug: UnresolvedRelation should retain SQL text position
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 16/Jan/21 19:21
Affects Version/s: 3.2.0

UnresolvedRelation should retain SQL text position. The following commands will be handled:
{code:java}
CACHE TABLE unknown
UNCACHE TABLE unknown
DELETE FROM unknown
UPDATE unknown SET name='abc'
MERGE INTO unknown1 AS target USING unknown2 AS source ON target.col = source.col WHEN MATCHED THEN DELETE
INSERT INTO TABLE unknown SELECT 1
INSERT OVERWRITE TABLE unknown VALUES (1, 'a')
{code}
Bug: Support Fallback Storage Cleanup during stopping SparkContext
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 17/Jan/21 05:17
Affects Version/s: 3.2.0

SPARK-33545 added `Support Fallback Storage during worker decommission` for the managed cloud-storage with TTL support. This issue aims to add additional clean-up feature during stopping SparkContext to save some money before TTL or the other HDFS-compatible storage which doesn't have TTL support.
Bug: Support complex types in pyspark.sql.functions.lit
Status: In Progress | Priority: Major | Resolution: 
Created: 16/Jan/21 13:30
Affects Version/s: 3.1.1

At the moment, Python users have to use dedicated function to create complex literal column. For example to create an array:

{code:python}
from pyspark.sql.functions import array, lit

xs = [1, 2, 3]
array(*[lit(x) for x in xs])
{code}

or map

{code:python}
from pyspark.sql.functions import create_map, lit, map_from_arrays
from itertools import chain

kvs = {"a": 1, "b": 2}

create_map(*chain.from_iterable(
    (lit(k), lit(v)) for k, v in kvs.items()
))

# or

map_from_arrays(
    array(*[lit(k) for k in kvs.keys()]),
    array(*[lit(v) for v in kvs.values()])
)
{code}

This is very verbose for such simple task. 

In Scala we have `typedLit` that addresses such cases

{code:scala}
scala> typedLit(Map("a" -> 1, "b" -> 2))
res0: org.apache.spark.sql.Column = keys: [a,b], values: [1,2]

scala> typedLit(Array(1, 2, 3))
res1: org.apache.spark.sql.Column = [1,2,3]

{code}


but its API is not Python-friendly.

It would be nice if {{lit}} could cover at least basic complex types.
Bug: Upgrade ZooKeeper to 3.6.2
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 14/Jan/21 05:35
Affects Version/s: 3.2.0

When running Spark on JDK 14:
{noformat}
21/01/13 20:25:32,533 WARN [Driver-SendThread(apache-spark-zk-3.vip.hadoop.com:2181)] zookeeper.ClientCnxn:1164 : Session 0x0 for server apache-spark-zk-3.vip.hadoop.com/<unresolved>:2181, unexpected error, closing socket connection and attempting reconnect
java.lang.IllegalArgumentException: Unable to canonicalize address apache-spark-zk-3.vip.hadoop.com/<unresolved>:2181 because it's not resolvable
	at org.apache.zookeeper.SaslServerPrincipal.getServerPrincipal(SaslServerPrincipal.java:65)
	at org.apache.zookeeper.SaslServerPrincipal.getServerPrincipal(SaslServerPrincipal.java:41)
	at org.apache.zookeeper.ClientCnxn$SendThread.startConnect(ClientCnxn.java:1001)
	at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1060)
{noformat}

Please see ZOOKEEPER-3779 for more details.