It's as simple as storing each user twice. Once with the key of id and once with the key of username.
A more compact way of doing this in terms of memory is to have usernames key to ids, so your username query would like like: query by username, get id; put in id, get info.
Unfortunately, there isn't a good way to have the same actual data be keyed on by two different keys.
For example, when you would insert a new user and then query for it:
redis 127.0.0.1:6379> HMSET id:4532143215432 username davejlong email [email protected]
OK
redis 127.0.0.1:6379> HMSET user:davejlong id 4532143215432 email [email protected]
OK
redis 127.0.0.1:6379> HGET id:4532143215432 username
"davejlong"
redis 127.0.0.1:6379> HGET user:davejlong id
"4532143215432"
redis 127.0.0.1:6379> HMGET user:davejlong email id
1) "[email protected]"
2) "4532143215432"
redis 127.0.0.1:6379> DEL user:davejlong
(integer) 1
redis 127.0.0.1:6379> DEL id:4532143215432
(integer) 1
Notice that when I am creating the user, I use HMSET twice. Now, I can query against either the username or the id. I also have to delete both keys now.