<Codis><JedisPool><DeadLock>

Overview

  • Background: I start a thread [call thread A below]in Spark driver to handle opening files in codis, in which I start six thread [call sub threads below]to handle the files in parallel.

  • What happened:

    • I found the codis openingFilePool never update since a given time.

    • So I looked into the Thread Dump tools of spark, and saw that thread A is always been WAITING. As below:

    • The normal one is as follow:

    • See the difference?
      The thread should be TIMED_WAITING(sleep), not be WAITING(wait for some other threads to awake it)!
    • It seems there is a deadlock?

  • Thread A get a jedis instance from JedisResourcePool to get all opening files.

  • Then, the sub threads handle these opening files and interact with codis in pipeline. [I use try(Pipeline pipeline = CodisPool.getPool().getResource().pipelined())]

Possible causes

  • I am not sure this is because 1) there is no enough instance in JedisPool; or 2) there is a deadlock
    • try (Pipeline pipeline = CodisPool.getPool().getResource().pipelined())
      • I am not sure whether this code will close jedis and pipeline, or it will just close pipeline?

    • JedisResourcePool is not thread-safe?

      • Some says that we should sync when we getResource() from JedisResourcePool. I am not sure.

      • And also I think should I configure the number of Jedis pool. 

 Final words

  • I have been wondering how to check whether the chained resource is closed. Uh... So I raised a question in stackoverflow.
  • Show the amzaing answer:
  • Try-with-resources close only variable, in your case Pipeline pipeline. You can read more in docs https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

    You can check it with example:

    MyResource class:

    class MyResource implements AutoCloseable {
    
        public SubResource getSubResource() {
            return new SubResource();
        }
    
        @Override
        public void close() throws Exception {
            System.out.println("Resource closed");
        }
    }

    SubResource class:

    class SubResource implements AutoCloseable{
        @Override
        public void close() throws Exception {
            System.out.println("SubResource closed");
        }
    }

    Main class:

    class Main {
    
        public static void main(String[] args) {
            try (SubResource s = new MyResource().getSubResource()) {
                System.out.println("Before closing");
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            System.out.println("After closing");
        }
    }

    Execution result:

    Before closing
    SubResource closed
    After closing
原文地址:https://www.cnblogs.com/wttttt/p/7202500.html