For the 1st part of your question:
There is no magic here, if you want to search across all your shards, you have to iterate over all shards. Jedis don't have this method, but you could extend ShardedJedis to add it (untested):
public Set<String> keys(String pattern) {
HashSet<String> found = new HashSet<String>();
for (Jedis jedis : getAllShards()) {
found.addAll(jedis.keys(pattern));
}
return found;
}
For the 2nd part of your question:
AFAIK, Jedis doesn't support transactions when using Shards, even if you do force the related keys to be on the same shard (see Jedis Advanced Usage).
This same link suggest a workaround that may apply for a few scenarios:
Mixed approach
If you want easy load distribution of ShardedJedis, but still need transactions/pipelining/pubsub etc, you can also mix the normal and the sharded approach: define a master as normal Jedis, the others as sharded Jedis. Then make all the shards slaveof master. In your application, direct your write requests to the master, the read requests to ShardedJedis. Your writes don't scale anymore, but you gain good read distribution, and you have transactions/pipelining/pubsub simply using the master. Dataset should fit in RAM of master. Remember that you can improve performance of the master a lot, if you let the slaves do the persistance for the master!