cpp-redis / cpp_redis

C++11 Lightweight Redis client: async, thread-safe, no dependency, pipelining, multi-platform
MIT License
713 stars 198 forks source link

sentinel reconnect problem, and the high availability example failed #39

Open neo1986 opened 5 years ago

neo1986 commented 5 years ago

Using the example of cpp_redis_high_availability_client Here is my docker-compose file and redis.conf: docker-compose file:

version: '2'

services:
  redis-master:
    image: redis:latest
    volumes:
        - ./redis-master.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf
    ports:
        - "8000:8000"

  redis-slave1:
     image: redis:latest
     volumes:
        - ./redis-slave1.conf:/etc/redis/redis.conf
     command: redis-server /etc/redis/redis.conf
     ports:
        - "8001:8001"

  redis-slave2:
     image: redis:latest
     volumes:
        - ./redis-slave2.conf:/etc/redis/redis.conf
     command: redis-server /etc/redis/redis.conf
     ports:
        - "8002:8002"

  redis-sentinel:
     image: redis:latest
     volumes:
        - ./redis-sentinel.conf:/etc/redis/redis.conf
     command: redis-sentinel /etc/redis/redis.conf
     ports:
        - "28000:28000"

redis-sentinel.conf:

port 28000

sentinel monitor test-master 10.88.231.131 8000 1

sentinel down-after-milliseconds test-master 30000

sentinel parallel-syncs test-master 1

sentinel failover-timeout test-master 180000

redis-master.conf: port 8000 redis-slave1.conf:


port 8001

slaveof 10.88.231.131 8000

slave-priority 100

slave-read-only yes

redis-slave2.conf

port 8002

slaveof 10.88.231.131 8000

slave-priority 10

slave-read-only yes

In the code, If I disable cpp_redis::network::set_default_nb_workers(2);, it will work then I stop the master, it won't try to reconnect the sentinel's new master and the programmer blocked and do nothing. if the cpp_redis::network::set_default_nb_workers(2); enabled, it will do nothing but block on the connect function

//! Enable logging
    cpp_redis::active_logger = std::unique_ptr<cpp_redis::logger>(new cpp_redis::logger);

    // disable this, it will work but won't reconnect after the master is down. 
    // cpp_redis::network::set_default_nb_workers(2);

    cpp_redis::client client;

    //! Add your sentinels by IP/Host & Port
    client.add_sentinel("10.88.231.131", 28000);

       // block on here.
    client.connect("test-master", [](const std::string& host, std::size_t port, cpp_redis::client::connect_state status) {
        if (status == cpp_redis::client::connect_state::dropped) {
            std::cout << "client disconnected from " << host << ":" << port << std::endl;
        }
    },
        0, -1, 5000);

cpp-redis is quite great and I think will replace the hiredis sooner or later, please take a look at this issue. the code is running on win with VS2015 and I installed the cpp-redis with vcpkg. please take a look at this issue, thanks a lot

dobeeisfree commented 5 years ago

Hi, @neo1986

This issue is not a problem, This is a specification.

Checkout this code and comment: https://github.com/cpp-redis/cpp_redis/blob/master/examples/cpp_redis_high_availability_client.cpp#L34-L35

So, the cpp_redis::network::set_default_nb_workers(2); code must be enabled. this code means that io service workers (threads numbers).

its default tcp library tacopie threadpool spec.

see:

These variable values(m_workers, ..._threads) are initialized to zero.

gzliurc commented 4 years ago
I found that
const std::shared_ptr<io_service>&
get_default_io_service(std::uint32_t num_io_workers) {
  if (io_service_default_instance == nullptr) {
    io_service_default_instance = std::make_shared<io_service>(num_io_workers);
  }
  else {
    //this code reset  thread_pool to 1  
    //io_service_default_instance->set_nb_workers(num_io_workers);
  }
  return io_service_default_instance;
}