Eh bien, cela dépend de la façon dont vous définissez la concurrence.
Dans les logiciels côté serveur, la concurrence et le parallélisme sont souvent considérés comme des concepts différents. Dans un serveur, la prise en charge des E/S simultanées signifie que le serveur est capable de servir plusieurs clients en exécutant plusieurs flux correspondant à ces clients avec une seule unité de calcul. Dans ce contexte, le parallélisme signifierait que le serveur est capable d'effectuer plusieurs choses en même temps (avec plusieurs unités de calcul), ce qui est différent.
Par exemple, un barman est capable de s'occuper de plusieurs clients alors qu'il ne peut préparer qu'une seule boisson à la fois. Ainsi, il peut fournir une concurrence sans parallélisme.
Cette question a été débattue ici :Quelle est la différence entre la concurrence et le parallélisme ?
Voir aussi cette présentation de Rob Pike.
Un programme à thread unique peut certainement fournir la simultanéité au niveau des E/S en utilisant un mécanisme de (dé)multiplexage des E/S et une boucle d'événements (ce que fait Redis).
Le parallélisme a un coût :avec les multiples sockets/multicœurs que l'on peut trouver sur le matériel moderne, la synchronisation entre les threads est extrêmement coûteuse. En revanche, le goulot d'étranglement d'un moteur de stockage performant comme Redis est bien souvent le réseau, bien avant le CPU. Les boucles d'événements isolées (qui ne nécessitent aucune synchronisation) sont donc considérées comme une bonne conception pour créer des serveurs efficaces et évolutifs.
Le fait que les opérations Redis soient atomiques est simplement une conséquence de la boucle d'événement à thread unique. Le point intéressant est que l'atomicité est fournie sans surcoût (elle ne nécessite pas de synchronisation). Il peut être exploité par l'utilisateur pour implémenter un verrouillage optimiste et d'autres modèles sans payer pour la surcharge de synchronisation.