public void Start(Action <ConsumedMessage> dataSubscriber, Action <Exception> errorSubscriber = null, Action closeAction = null)
        {
            if (_running)
            {
                return;
            }

            var consumerOptions = new ConsumerOptions
            {
                GroupName  = _group,
                AutoCommit = _autoCommit
            };

            do
            {
                if (_restart)
                {
                    Task.Delay(RestartMsDelay).Wait();
                }

                lock (Lock)
                {
                    Logger.Info($"Starting balanced consumer {_group} for {_topic}.");
                    _restart = false;

                    try
                    {
                        var consumer = _client.Consumer(consumerOptions);

                        _instance = consumer.Join();
                        _instance.ZookeeperSessionExpired += (sender, args) =>
                        {
                            OnZookeeperSessionExpired();
                            Logger.WarnFormat($"Zookeeper session expired. Shutting down consumer {_group} for {_topic} to restart...");
                            Restart();
                        };
                        _instance.ZookeeperDisconnected += (sender, args) =>
                        {
                            OnZookeeperDisconnected();
                            Logger.WarnFormat($"Zookeeper disconnected. Shutting down consumer {_group} for {_topic} to restart...");
                            Restart();
                        };
                        _instance.Rebalanced += (sender, args) => OnRebalanced(args);

                        _streams = _instance.Subscribe(_topic, _threads).ToArray();

                        _streams.ForEach(s =>
                        {
                            s.Data(m =>
                            {
                                try
                                {
                                    dataSubscriber(m);

                                    if (!_autoCommit)
                                    {
                                        _instance.Commit(_topic, m.Partition, m.Offset);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Logger.Error($"Exception in consumer {_group} for {_topic}. Restarting...", ex);
                                    errorSubscriber?.Invoke(ex);

                                    Restart();
                                }
                            });

                            if (errorSubscriber != null)
                            {
                                s.Error(errorSubscriber);
                            }

                            s.Start();
                        });

                        Logger.Info($"Consumer {_instance.Id} started with {_streams.Count()} threads.");

                        _running = true;
                    }
                    catch (Exception ex)
                    {
                        Logger.Error($"Exception starting consumer {_group} for {_topic}. Restarting...", ex);
                        Restart();
                        continue;
                    }
                }

                foreach (var s in _streams)
                {
                    s.Block();
                }

                Logger.Info($"Consumer {_group} for {_topic} shut down.");
            } while (_restart);

            closeAction?.Invoke();
            _running = false;
        }